一、信号与槽机制
特别鸣谢B站大轮明王讲Qt的讲解:大轮明王讲Qt的个人空间_哔哩哔哩_bilibili
信号与槽机制(Signal and Slot)是一种在软件开发中广泛使用的通信机制,主要用于处理事件驱动的程序设计。它是Qt框架中的一项重要特性,也被其他编程框架和库所采用。
信号(Signal)是对象发出的事件或状态的通知,它可以被其他对象接收并作出响应。槽(Slot)是处理信号的特定函数或方法。当信号发出时,与之关联的槽函数将被自动调用。信号和槽之间通过连接(Connection)建立联系。
使用信号与槽机制,可以实现对象之间的松散耦合。一个对象可以将自己的信号与其他对象的槽函数进行连接,使得事件发生时能够自动触发相应的响应处理。这种机制使得程序的编写更加灵活和可维护,因为对象之间的交互不需要显式的调用。
二、信号与槽直接连接
直接连接(Direct Connection)是一种信号与槽之间的连接方式。在直接连接中,当信号发出时,槽函数会立即执行,不经过事件队列的处理,是一种同步的连接方式。直接连接适用情况:
1、函数和槽在同一个线程中.
2、函数和槽函数的执行时间较短,可以立即处理。
连接方式:
QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()), Qt::DirectConnection);
其中sender表示信号的发送者,signal表示发送的信号,receiver表示信号的接收者,slot表示执行的槽函数。
2.1、QT4中SIGNAL和SLOT包裹连接
在QT中支持connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));这样的连接方式,但这样的连接方式存在一定的缺点:使用这种方式时,编译器不会做错误检查,即使函数名或者参数写错了,也能够编译通过,将问题留在了运行的时候,无法尽早发现问题。
//1、使用QT4 SIGNAL/SLOT连接
connect(ui->btnSignalandSlot,SIGNAL(clicked()),this,SLOT(showMaximized()));
这里在引入了按钮btnSignalandSlot,发送按键按下事件,执行槽函数对MainWindow窗口的最大化显示。
2.2、QT5中使用函数地址进行连接
这种方式中函数和槽都是用地址的形式进行连接
connnect(sender,&sender::signal,receiver,&receiver::slot);
这种方式能够在编译阶段就对函数类型、参数个数、参数类型等进行检查。
connect(ui->btnFunctionAddress,&QPushButton::clicked,this,&MainWindow::showNormal);
这里添加按钮btnFunctionAddress,当按钮按下时执行输出窗口正常显示。
2.3、通过UI界面选中按钮并转到槽
这种方式本质上还是通过QT4版的那种连接方式,通过转到槽后,Qt Creator将自动声明和创建函数,在创建的函数体中编辑要执行的槽函数即可。
这里执行槽函数后设置了输出窗口的标题内容。
2.4、通过UI界面的信号槽编辑页面进行连接
这种方法和2.3的转到槽连接类似,但这种方式更便于理解,更加形象。
发送者选择发送的控件,信号则是发送信号类型,接收者即接收目标,槽即要执行的内容和函数。需要添加或删除多个连接时点击右上角的“加号”和“减号”即可。这里添加了按钮btnUIEditSlot发送点击响应函数,执行对应用程序窗口全屏显示的的内容。
2.5、Lambda表达式连接
Lambda表达式是一种匿名函数方式,也可以称为闭包,它是一种简洁、方便的方式来表示和定义函数。在C++11中的形式为:
[ captures ] ( arguments ) -> return_type { body }
-
[captures]
:可选的捕获列表,用于指定Lambda表达式中使用的外部变量。可以通过值捕获或引用捕获来获取外部变量的值。
-
(arguments)
:参数列表,指定Lambda函数接受的参数。参数可以是零个或多个。
-
-> return_type
:箭头符号(->
)后面是返回类型,用于指定Lambda函数的返回值类型。
-
{ body }
:函数体,包含Lambda函数的具体实现。可以是一行简单的表达式,也可以是多行语句块。
connect(ui->btnLambda,&QPushButton::clicked,this,[&](){this->close();});
这里创建按钮名为btnLambda,发送按钮点击信号,应用程序窗口执行关闭的槽函数。