类静态中发信号,基本上传入类指针到发信号处,不管是全局变量,还是类指针
输出结果
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;
}
void SetInstanceSelf(AddCallBack* p){m_pInstance = p;}
static AddCallBack* GetInstanceSelf() {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()
{
m_pInstance = this;// 很怪的模样
}
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.或者传入的参数为
// 一般操作都是这样进行回调,AddCallBack* xxx 改为void*,设置回调处,传入别的类指针,在回调处进行调研.
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);
// 方式4: 传递指针,设置静态指针的方式,
AddCallBack add1;
// add1.SetInstanceSelf(&add1);或者初始化时,赋值为this,有点儿怪.
connect(&add1,SIGNAL(sig_Add(QString,int)),this,SLOT(add(QString,int)));
addInstance->SubSelf(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 调用端开始调用了");
}