qt 類靜態函數中發信號 和回調函數的基本使用

類靜態中發信號,基本上傳入類指針到發信號處,不管是全局變量,還是類指針

輸出結果
Widget::add :  "形參類" 7
Widget::add :  "全局類" 2
Widget::add :  "單例類" -4
 set call
"調用端開始調用了" : 回調函數 myfunc 調用 OK 
 set call
"new call func 調用端開始調用了" : 回調函數 myfunc2 調用 OK 
 set call
"using 調用端開始調用了" : 回調函數 myfunc3 調用 OK 
 set call
"static widget 調用端開始調用了" : 回調函數 Widget::myfunc4 調用 OK 
#ifndef ADDCALLBACK_H
#define ADDCALLBACK_H
#include <QObject>
#pragma execution_character_set("utf-8")

class AddCallBack : public QObject
{
    Q_OBJECT

public:
    AddCallBack();
    // 設置單例類
    static AddCallBack* GetInstance()
    {
        if ( m_pInstance == NULL )
        {
            if( m_pInstance == NULL )
            {
                m_pInstance = new AddCallBack();
            }
        }

        return m_pInstance;
    }
public:
    static void Add(int x,int y);

    static void Add(AddCallBack* xxx, int x, int y);
    static void Sub(int x,int y);

signals:
    void sig_Add(QString,int);
 private:
    static AddCallBack* m_pInstance;
};

#endif // ADDCALLBACK_H

// addcallback.cpp
#include "addcallback.h"

AddCallBack g_add;
AddCallBack* AddCallBack::m_pInstance = nullptr;

AddCallBack::AddCallBack()
{

}

void AddCallBack::Add(int x, int y)
{
    // 發信號
    // emit sig_Add(1);//  “AddCallBack::sig_Add”: 非靜態成員函數的非法調用
    // 1.需要通過全局變量或者單例模式的來獲取,
    // 或者傳入的調用的信號類,如 void AddCallBack::Add(AddCallBack* xxx,int x, int y)
    emit g_add.sig_Add("全局類",x+y);// 全局
//    g_add.sig_Add("全局類",x+y);
}


void AddCallBack::Add(AddCallBack* xxx,int x, int y)
{
    // 發信號
    // emit sig_Add();//  “AddCallBack::sig_Add”: 非靜態成員函數的非法調用
    // 1.需要通過全局變量或者單例模式的來獲取,
    // 2.或者傳入的參數爲
    emit xxx->sig_Add("形參類",x+y);
}

void AddCallBack::Sub(int x, int y)
{
   emit AddCallBack::GetInstance()->sig_Add("單例類",y-x);
}

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#pragma execution_character_set("utf-8")

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
public :
    static void myfunc4(QString str);

private slots:
    void on_pushButton_clicked();


    void on_pushButton_2_clicked();

public slots:
    void add(QString str,int x);
private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

#include "widget.h"
#include "ui_widget.h"
#include "addcallback.h"
#include <QDebug>

#include <chrono>
#include <thread>

// std::funtion c++11可調用對象包裝器
#include <functional>

extern AddCallBack g_add;
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    AddCallBack add;

    connect(&add,SIGNAL(sig_Add(QString,int)),this,SLOT(add(QString,int)));// 綁定

    // AddCallBack::Add(3,4);// 想通過發信號的方式,處理其他的事情

    // 方式1:在靜態裏面發送信號
    AddCallBack::Add(&add,3,4);// 傳入指定的信號的方式,傳入的參數是回調函數類

    // 綁定全局變量
    connect(&g_add,SIGNAL(sig_Add(QString,int)),this,SLOT(add(QString,int)));
    // 方式2: 這裏的靜態函數傳入的類,可以是全局變量這種簡單,但不建議
    AddCallBack::Add(1,1);

    // 方式3: 可以弄成單例類的形式,這裏的構造就不設成 private
    AddCallBack* addInstance =   AddCallBack::GetInstance();
    connect(addInstance,SIGNAL(sig_Add(QString,int)),this,SLOT(add(QString,int)));
    addInstance->Sub(6,2);
}

void Widget::add(QString str,int x)
{
    qDebug() << "Widget::add : " << str<< x;
}

// ==============================================================
// 回調函數部分
typedef void FuncCallBack(QString str);

FuncCallBack* g_con = nullptr;// 保存回調函數地址.

int setCallbacks(FuncCallBack* cl)
{
     qDebug() << " set call";
     g_con = cl;
     return 0;
}

void myfunc(QString str)
{
    qDebug()<< str << ": 回調函數 myfunc 調用 OK " ;
}

void myfunc2(QString str)
{
    qDebug()<< str << ": 回調函數 myfunc2 調用 OK " ;
}

void myfunc3(QString str)
{
    qDebug()<< str << ": 回調函數 myfunc3 調用 OK " ;
}

void Widget::myfunc4(QString str)
{
    qDebug()<< str << ": 回調函數 Widget::myfunc4 調用 OK " ;
}

void Widget::on_pushButton_2_clicked()
{
    // 1.設置 函數地址 方式進行設置回調函數
    setCallbacks(&myfunc);// 調用處,設置回調函數

    // 仿照調用回調函數,一般設置回調後,在這個程序中某接口之後調用.
    std::this_thread::sleep_for(std::chrono::seconds(2));
    g_con("調用端開始調用了");

    // 2. 用新的函數指針來接.而不是FuncCallBack
    void(*pmy)(QString) = myfunc2;// &myfunc
    setCallbacks(pmy);

    std::this_thread::sleep_for(std::chrono::seconds(2));
    g_con("new call func 調用端開始調用了");


    // 3. using 關鍵字的使用
    using ufunc = void(*)(QString);// 定義函數指針類型
    ufunc  tmpUf ;// 類型 定義變量
    tmpUf = myfunc3;// 變量賦值
    setCallbacks(tmpUf);

    std::this_thread::sleep_for(std::chrono::seconds(2));
    g_con("using 調用端開始調用了");


    // 4.類成員靜態函數指針(Widget)
//    using ufunc2 = void(*)(QString);
//    ufunc2 uFunc2;
//    uFunc2 = Widget::myfunc4;
//    setCallbacks(uFunc2);

    setCallbacks(Widget::myfunc4);

    std::this_thread::sleep_for(std::chrono::seconds(2));
    g_con("static widget 調用端開始調用了");

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章