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;
    }
      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 调用端开始调用了");

}

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值