QT信号与槽

您所在的位置:网站首页 qt中的emit QT信号与槽

QT信号与槽

2024-01-03 23:44| 来源: 网络整理| 查看: 265

QT信号与槽——观察者模式——回调函数 1、QT信号与槽机制 1.1信号本质

信号是由于用户对窗口或控件进行了某些操作,导致窗口或控件产生了某个特定事件,这时候 Qt 对应的窗口类会发出某个信号。比如:信号的本质是事件

按钮单击、双击窗口刷新鼠标移动、鼠标按下、鼠标释放键盘输入

在QT中信号的发出者是某个实例化的类对象,对象内部可以进行相关事件的检测。

1.2槽的本质

在 Qt 中槽函数是一类特殊的功能的函数,在编码过程中也可以作为类的普通成员函数来使用。之所以称之为槽函数是因为它们还有一个职责就是对 Qt 框架中产生的信号进行处理。

比如:和朋友一起玩游戏(csgo),朋友说:我要丢闪了,于是我背身一下防闪;

实例对象角色描述朋友信号发出者信号携带的信息: 我要丢闪了我信号接收者处理朋友发射的信号: 背身

在Qt中槽函数的所有者也是某个类的实例对象。

1.3信号和槽关系

在 Qt 中信号和槽函数都是独立的个体,本身没有任何联系,但是由于某种特性需求我们可以将二者连接到一起,在 Qt 中我们需要使用 QOjbect类中的 connect 函数进二者的关联。

QMetaObject::Connection QObject::connect( const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection); /*参数: - sender: 发出信号的对象 - signal: 属于sender对象, 信号是一个函数, 这个参数的类型是函数 指针, 信号函数地址 - receiver: 信号接收者 - method: 属于receiver对象, 当检测到sender发出了signal信号, receiver对象调用method方法,信号发出之后的处理动作*/ // 参数 signal 和 method 都是函数地址, 因此简化之后的 connect() 如下:框架自动调用 connect(const QObject *sender, &QObject::signal, const QObject *receiver, &QObject::method); 2、标准信号槽

QT自带的一些信号与槽函数

3、自定义信号槽

Qt 框架提供的信号槽在某些特定场景下是无法满足我们的项目需求的,因此我们还设计自己需要的的信号和槽,同样还是使用 connect () 对自定义的信号槽进行连接。

如果想要在QT类中自定义信号槽, 需要满足一些条件, 并且有些事项也需要注意:

注意要编写新的类并且让其继承Qt的某些标准类这个新的子类必须从QObject类或者是QObject子类进行派生在定义类的头文件中加入 Q_OBJECT 宏不加无法使用QT的信号槽机制 // 在头文件派生类的时候,首先像下面那样引入Q_OBJECT宏: class MyMainWindow : public QWidget { Q_OBJECT ...... } #ifndef MAINWINDOW_H #define MAINWINDOW_H #include /* 引入 QPushButton */ #include class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); signals: /* 声明一个信号,只需声明,无需定义 */ void pushButtonTextChanged(); }; #endif // MAINWINDOW_H 3.1自定义信号

信号是类的成员函数,返回值必须是 void 类型,信号的名字可以根据实际情况进行指定,参数可以随意指定, 信号也支持重载,信号需要使用 signals 关键字进行声明, 使用方法类似于public等关键字,信号函数只需要声明, 不需要定义(没有函数体实现),在程序中发射自定义信号: 发送信号的本质就是调用信号函数,习惯性在信号函数前加关键字: emit, 但是可以省略不写,emit只是显示的声明一下信号要被发射了, 没有特殊含义,底层 emit == #define emit

// 举例: 信号重载 // Qt中的类想要使用信号槽机制必须要从QObject类派生(直接或间接派生都可以) class Test : public QObject { Q_OBJECT signals: void AA(); // 参数的作用是数据传递, 谁调用信号函数谁就指定实参 // 实参最终会被传递给槽函数 void AA(int a); }; 3.2自定义槽 自定义槽注意事项返回值必须是 void 类型槽也是函数, 因此也支持重载槽函数需要指定多少个参数, 需要看连接的信号的参数个数槽函数的参数是用来接收信号传递的数据的, 信号传递的数据就是信号的参数信号函数: void AA(int a, double b);槽函数: void AA(int a, double b);槽函数的参数应该和对应的信号的参数个数,从左到右类型依次对应信号的参数可以大于等于槽函数的参数个数 == 信号传递的数据被忽略了信号函数: void AA(int a, double b);槽函数: void AA(int a);Qt中槽函数的类型是多样的Qt 中的槽函数可以是类的成员函数、全局函数、静态函数、Lambda表达式(匿名函数)槽函数可以使用关键字进行声明: slots (Qt5中slots可以省略不写)public slots:private slots: –> 这样的槽函数不能在类外部被调用protected slots: –> 这样的槽函数不能在类外部被调用。 // class A class A : public QObject { Q_OBJECT public: explicit A(QObject *parent = nullptr); signals: void sig(); // 不能表达出想要吃什么 void sig(QString msg); // 可以通过参数表达想要吃什么 }; // class B class B : public QObject { Q_OBJECT public: explicit B(QObject *parent = nullptr); public slots: // 槽函数 void slo(); // 不能知道信号发出者要吃什么 void slo(QString msg); // 可以知道信号发出者要吃什么 }; 4、信号槽扩展

信号与槽可以多对一,也可以一对多

QT4连接方式

QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));

QT5及以上连接方式

connect(const QObject *sender, &QObject::signal, const QObject *receiver, &QObject::method);

用QT5的连接方式时要注意槽函数重载问题,使用函数指针,比如:

// 定义函数指针指向重载的某一个具体的信号地址 void (Me::*mysignal)(QString) = &Me::eat; // 定义函数指针指向重载的某一个具体的槽函数地址 void (Me::*myslot)(QString) = &Me::hungury; // 使用定义的函数指针完成信号槽的连接 connect(&m, mysignal, &m, myslot);

最好使用QT5的连接方式,因为这样能检查出错误,QT4的使用宏定义把函数名变为字符串,即使写错了也不会报错;

参考:Qt开发编程-入门基础教程Qt5

【正点原子】 I.MX6U 嵌入式 Qt 开发指南 V1.0



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3