C++_之Qt的信号和槽的详解
1、概述
信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。(这里提一句,Qt 的信号槽使用了额外的处理来实现,并不是 GoF 经典的观察者模式的实现方式。)
信号和槽是Qt特有的信息传输机制,是Qt设计程序的重要基础,它可以让互不干扰的对象建立一种联系。
槽的本质是类的成员函数,其参数可以是任意类型的。和普通C++成员函数几乎没有区别,它可以是虚函数;也可以被重载;可以是公有的、保护的、私有的、也可以被其他C++成员函数调用。唯一区别的是:槽可以与信号连接在一起,每当和槽连接的信号被发射的时候,就会调用这个槽。
1.1对象树(子对象动态分配空间不需要释放)
参考连接:https://blog.csdn.net/fzu_dianzi/article/details/6949081
Qt提供了一种机制,能够自动、有效的组织和管理继承自QObject的Qt对象,这种机制就是对象树。
Qt对象树在用户界面编程上是非常有用的。它能够帮助程序员减轻内存泄露的压力。
比如说当应用程序创建了一个具有父窗口部件的对象时,该对象将被加入父窗口部件的孩子列表。当应用程序销毁父窗口部件时,其下的孩子列表中的对象将被一一删除。这让我们在编程时,能够将主要精力放在系统的业务上,提高编程效率,同时也保证了系统的稳健性。
下面笔者将简单分析对象树。
代码验证:
int main(int argc, char *argv[]) { QApplication app(argc, argv); QDialog *dlg = new QDialog(0); QPushButton *btn = new QPushButton(dlg); qDebug() << "dlg = " << dlg; qDebug() << "btn = " << btn; dlg->exec(); delete btn; qDebug() << "dlg = " << dlg; return 0; } dlg = QDialog(0x3ea1a0) btn = QPushButton(0x3ea228) /*关闭窗口后,dlg = QDialog(0x3ea1a0) 这说明关闭窗口,不会销毁该窗口部件,而是将其隐藏起来。 我们在qDebug() << "dlg = " << dlg; 之后加上 qDebug() << "btn = " << btn; 明显的,我们之前已经delete btn,btn指针没有被赋值为0,这是编译器决定的。 执行程序后,必然出现段错误。 2、 将程序稍微修改下。*/ int main(int argc, char *argv[]) { QApplication app(argc, argv); QDialog *dlg = new QDialog(0); QPushButton *btn = new QPushButton(dlg); qDebug() << "dlg = " << dlg; qDebug() << "btn = " << btn; dlg->exec(); delete dlg; qDebug() << "btn = " << btn; return 0; }
2、信号和槽
为了体验一下信号槽的使用,我们以一段简单的代码说明:
Qt5 的书写方式:(推荐的使用)★★★★★
#include <QApplication> #include <QPushButton> int main(int argc, char *argv[]) { QApplication app(argc, argv); QPushButton button("Quit"); QObject::connect(&button, &QPushButton::clicked, &app, &QApplication::quit); button.show(); return app.exec(); }
我们按照前面文章中介绍的在 Qt Creator 中创建工程的方法创建好工程,然后将main()函数修改为上面的代码。点击运行,我们会看到一个按钮,上面有“Quit”字样。点击按钮,程序退出。
connect()函数最常用的一般形式:
connect(sender, signal, receiver, slot);
参数:
sender:发出信号的对象
signal:发送对象发出的信号
receiver:接收信号的对象