Qt教程-信号槽

要使用Qt就不得不提到信号槽,信号槽(signal 和 slot)是QT的核心机制之一。
我们都知道界面是通过用户给出的操作进行反馈的。比如Windows系统上的一个窗口上存在一个按钮,当用户在这个按钮上按下鼠标左键后,Windows会向这个窗口发送一条WM_LBUTTONDOWN消息,当用户抬起鼠标左键时Windows会向窗口发送一条WM_LBUTTONUP消息,程序通过一个线程循环处理这些窗口上发生的消息作出响应,最终形成的效果可能是,用户单击了一个按钮,程序弹出了一个提示信息。
通过循环响应各种消息程序就能作出各种各样的反映。在传统的开发模式中开发者需要自己创建消息循环,处理各种消息,然后再调用对应的处理函数。不得不说这样实在很麻烦。
信号槽这个机制本身有点像处理消息队列,有所不同的是开发者无需处理自己不关心的事件。当一个事件发生的时候(比如:鼠标点击事件)会产生一个信号,Qt会寻找和这个信号关联在一起的函数,并调用这个函数,通过这样的方式完成响应。在这样的流程下开发者要做的事情就很简单了,把响应操作的函数和信号关联起来就行了。和传统的处理消息队列相比,不用自行维护一个消息处理循环,不用考虑线程阻塞等一些问题,只要专注与自己想处理的信号就可以了,这样无疑方便了开发者。
信号槽的使用非常的简单,使用connect函数连接信号和处理函数就可以了。连接之后一旦有信号发生则会自动调用处理函数。
我们可以看到例子hello_world.cpp

编译运行后运行能看到一个按钮,按下按钮后会产生如下图的效果。

QApplication类我们前面介绍过用来管理GUI程序的控制流和主设置。它包含主事件循环,用来处理窗口的各种事件。
QLabel是一个标签控件,标签控件通常用于显示各种信息。
QPushButton则是按钮控件,界面上的各种按钮由此控件提供。
QObject::connect是信号槽的连接函数。
我们可以看到,代码中定义了2个QLabel控件,分别是label和label2,分别使用Hello, world和Hello, world2这两个字符串进行初始化。随后我们还定义了一个QPushButton控件,QPushButton是按钮控件用来提供界面上的各种按钮。我们使用Show Hello初始化QPushButton类,最终的效果就是按钮上显示的文字为Show Hello。
随后我们调用了2次connect函数,QObject::connect函数的作用是吧信号和槽关联起来。
connect有下面几种重载

我们简化一下,常用的大约有这样的两种形式。

我们这里的调用同样也符合这两种形式,sender我们都为button对象,也就是按钮。signal在本例中都是QPushButton::clicked,QPushButton::clicked这个信号在被鼠标左键点击的时候会发出。本例中第一次调用connect符合connect(sender,signal,function)这种形式,Lambda表达式可以当成是一个没有名字的函数。第二次的调用符合connect(sender,signal,receiver,slot)这种形式,发出的信号由label对象作为接收者,最后调用show这个函数。
一个信号可以连接多个槽函数,所以最终会看到启动了2个新窗口。前面的例子中演示了connect的两种用法。SIGNAL和SLOT宏作用是把函数转换成字符串。在QT5之前这样是标准做法,但是编译器无法检查字符串的合法性,容易出错,故新版本中推荐直接connect而尽可能不要使用SIGNAL和SLOT宏。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.