简介 #
信号和槽是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的帮助文档中查看。