设置信号和槽
在本教程中,我们将学习带有信号和槽机制的 QtGUI 项目。
文件->新建文件或项目…
应用程序->Qt Gui 应用程序->选择…
默认情况下,我们将类保留为MainWindow。
下一步->完成
让我们通过双击mainwindow.ui来打开Forms来放置 gui 组件:
从小部件中,拖动水平滑块和进度条,并将它们放入主窗口。然后,
运行代码。现在,如果我们移动滑块,进度将反映滑块的变化:
我们是通过 gui 完成的,但我们可以通过直接编程来完成。
让我们删除信号槽,在MainWindow类的构造函数中编写信号槽机制的代码,如下图:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->horizontalSlider,
SIGNAL(valueChanged(int)),
ui->progressBar,
SLOT(setValue(int)));
}
MainWindow::~MainWindow()
{
delete ui;
}
信号和插槽
信号和槽用于对象之间的通信。信号和槽机制是 Qt 的核心特性,可能也是与其他框架提供的特性最不同的部分。
在 GUI 编程中,当我们更改一个小部件时,我们经常希望通知另一个小部件。更一般地说,我们希望任何类型的对象都能够相互通信。例如,如果用户单击关闭按钮,我们可能希望调用窗口的 close() 函数。较旧的工具包使用回调实现这种通信。回调是指向函数的指针,因此如果您希望处理函数通知您某个事件,您可以将指向另一个函数(回调)的指针传递给处理函数。然后,处理函数会在适当的时候调用回调。回调有两个基本缺陷:首先,它们不是类型安全的。我们永远无法确定处理函数是否会使用正确的参数调用回调。第二,在 Qt 中,我们有一个回调技术的替代方案:我们使用信号和槽。当特定事件发生时会发出信号。Qt 的小部件有许多预定义的信号,但我们总是可以子类化小部件以向它们添加我们自己的信号。插槽是响应特定信号而调用的函数。Qt 的小部件有许多预定义的插槽,但通常的做法是子类化小部件并添加自己的插槽,以便您可以处理您感兴趣的信号。
信号和槽机制是类型安全的:信号的签名必须与接收槽的签名匹配。(事实上,一个槽的签名可能比它接收的信号更短,因为它可以忽略额外的参数。)由于签名是兼容的,编译器可以帮助我们检测类型不匹配。信号和槽是松散耦合的:发出信号的类既不知道也不关心哪个槽接收信号。Qt 的信号和槽机制确保如果将信号连接到槽,则将在正确的时间使用信号的参数调用槽。信号和槽可以接受任意数量的任意类型的参数。它们是完全类型安全的。
从 QObject 或其子类之一(例如,QWidget)继承的所有类都可以包含信号和槽。当对象以可能对其他对象感兴趣的方式改变其状态时,信号由对象发出。这就是对象进行通信的全部内容。它不知道也不关心是否有任何东西在接收它发出的信号。这是真正的信息封装,并确保对象可以用作软件组件。
槽可以用来接收信号,但它们也是普通的成员函数。就像一个对象不知道是否有任何东西接收到它的信号一样,一个槽也不知道它是否有任何信号连接到它。这确保了可以使用 Qt 创建真正独立的组件。您可以将任意数量的信号连接到单个插槽,并且可以将信号连接到任意数量的插槽。甚至可以将一个信号直接连接到另一个信号。(这将在第一个信号发出时立即发出第二个信号。)