類靜態中發信號,基本上傳入類指針到發信號處,不管是全局變量,還是類指針
輸出結果
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 調用端開始調用了");
}