跳至正文
View Categories

< 1 min read

简介 #

信号和槽是Qt的消息传输机制,可以将多个独立的单元关联起来。

我们生活中也有非常多信号和槽的案例,只是叫法不同罢了。比如,闹钟响了就通知我们该起床了,上课铃响了就意味着该进教室上课了,在Qt中把闹钟响了,上课铃响了这种叫做信号,把起床和上课这种对应的事件叫做槽。也就是说,当一个信号发出时,对应的槽(函数)就会来响应。

也可以这么理解,如果(信号)那么(槽函数)。

一个事件定义为信号和槽并不是固定的,而是根据项目开发的实际需要来进行。比如,我们开发一款闹钟软件的时候,可以设置当时间到7:00时为信号,对应的槽函数为响铃(播放音乐)。

绑定 #

上面我们举的例子中,为什么闹钟响了对应着起床,上课铃响了对应着上课,而不是上课铃响了对应着起床呢?

因为我们大脑中提前就绑定好了对应事件的关联性,同样,在Qt中我们也可以把对应的信号和槽进行关联,从而达到我们预期的设定。

Qt库中提供了大量常用的信号和槽函数,也支持自定义信号和槽函数。

在绑定信号和槽函数之前,我们需要知道不同的对象自带有哪些信号和槽。以QLabel为例,打开帮助文档查看。

QLineEdit类的信号和槽函数。

我们可以使用connect函数将信号和槽进行连接,格式如下。

connect(信号发送者,发送的具体信号(参数),信号的接收者,接收者对应的槽函数(参数 ));

实践 #

我们将要实现一个Label内容随着LineEdit内容变化而自动更新的程序。

在第一个hello world程序的界面上在加入一个LineEdit组件,并调整好位置。这个界面实际上就是MainWindow类对应的UI。

运行预览界面,此时并无实际功能。

打开MainWindow类的构造函数,初始状态如下。

我们在构造函数加入自己的功能代码。

QObject::connect(ui->lineEdit, SIGNAL(textChanged(const QString)),    ui->label, SLOT(setText(const QString &)));

完成后如下图,9,10行为我们新增的代码。

编译运行后,我们在LineEdit中输入,Label内容会立即和LineEdit同步。

以上我们就通过信号和槽的链接实现了不同对象之间的消息传递。

总结 #

在使用connect函数时,我们必须明确信号发送者,发送信号的内容,信号接收者,接收者响应的槽函数这四个基本信息。

connect是QObject类的静态成员函数,函数声明如下。

inline QMetaObject::Connection QObject::connect(const QObject *asender, const char *asignal,                                            const char *amember, Qt::ConnectionType atype) const

可以看出,信号发送者和接收者必须是指针。信号和槽函数也是指针形式,但一般情况下Qt要求使用SIGNAL()和SLOT()这两个宏进行处理后使用。

信号和槽的消息传输机制非常灵活,既可以信号绑定槽函数,也可以信号绑定信号,又可以一个信号对应多个槽函数和信号。

更多关于signal,slot,connect的内容可以在Qt的帮助文档中查看。