当前位置:网站首页>QT信号与槽连接(松耦合)
QT信号与槽连接(松耦合)
2022-07-26 19:33:00 【霸道小明】
GUI用户界面中,当用户操作一个窗口部件时,需要其他窗口部件响应,传统方式经常使用callback(回调机制)来实现。所谓回调即事先将函数指针作为参数传递另一个函数,然后在函数处理过程中适当地方调用回调函数回调机制有两个缺陷:类型不安全,不能保证调用函数过程中使用正确的参数;强耦合,处理函数必须知道调用哪个回调函数。Qt的信号与槽机制是类型安全的,松耦合,更灵活,更方便。
信号与槽(Signal & Slot)是 Qt 编程的基础,也是 Qt 的一大创新。因为有了信号与槽的编程机制,在 Qt 中处理界面各个组件的交互操作时变得更加直观和简单。
信号(Signal)就是在特定情况下被发射的事件,例如PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号。发射信号使用Qt的emit关键字。QT 的 signals 关键字指出进入了信号声明区,随后即可声明自己的信号。
在对话窗口上放三个控件,当点击对应控件时在DeBug输出“XXX加油 ”字样。

槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以声明在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。
我们可以使用右键的方式给控件添加槽方法。也可也按on_对象名_事件名的格式手动添加槽方法,按这种格式添加的槽方法可以自动与单击时发射的 clicked() 信号连接。
private slots:
void on_whBtn_clicked();
void on_zgBtn_clicked();
void on_sjBtn_clicked(); //自动连接 on_对象名_信号名关键字signals定义一个信号,当控件点击的槽方法执行时我们让其发出这个信号。
signals:
void Commeon(QString& str); //信号不能也无需实现,且返回值是void使用emit关键字发送信号 。
void MainWindow::on_whBtn_clicked()
{
QString str="武汉加油";
emit Commeon(str);
}
void MainWindow::on_zgBtn_clicked()
{
QString str="中国加油";
emit Commeon(str);
}
void MainWindow::on_sjBtn_clicked()
{
QString str="世界加油";
emit Commeon(str);
}我们再准本一个槽方法,用来与上面的信号关联;槽方法将一个CString在DeBug中打印出
private slots:
void CommeonGuys(QString& str);
void MainWindow::CommeonGuys(QString& str)
{
qDebug()<<str;
}在构造函数中将信号与上面新定义的槽方法绑定起来
connect(this,SIGNAL(Commeon(QString&)),this,SLOT(CommeonGuys(QString&)));信号与槽关联是用 QObject::connect() 函数实现:
QMetaObject::Connection QObject::connect(
const QObject *sender, //信号发送者
const char *signal, //发送的信号
const QObject *receiver, //信号接收者
const char *method, //表示与信号连接的方式的字符串,可以是槽或信号
Qt::ConnectionType type = Qt::AutoConnection //连接方式,默认自动连接
)常用格式:connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
信号使用SIGNAL,对于槽则使用SLOT,用它们将函数的原型包围起来即可。注意connect方法采用SIGNAL()及SLOT()时,这里的函数原型只能写出类型,不能有任何参数名,否则连接将会失败。
同时信号与槽连接方式:
- Qt::AutoConnection:(默认连接方式)自动方式,由系统自动选择连接方式。
- Qt::DirectConnection:直接方式,信号发射时,立即调用槽。
- Qt::QueuedConnection:队列方式,信号发射时产生一个事件进入队列,事件被处理时槽才能调用。
- Qt::BlockQueuedConnection:阻塞队列方式,信号发射时产生一个事件进入队列,然后当前线程进入阻塞状态,直到事件处理完毕,若接收方位于发送信号的线程中,则程序会死锁,故此连接方式仅用于多线程。
也可以不使用SIGNAL和SLOT,直接取地址。
connect(this,&MainWindow::Common,this,&MainWindow::CommonGuys);信号可以看做是特殊的函数,需要带括号,可带参数,信号无需实现也不能实现。槽函数需要带括号,有参数时还需要指明参数。当信号和槽函数带有参数时,在 connect()函数里,要写明参数的类型。信号的参数需与槽的参数列表一致,允许比槽参数多。如果不匹配或参数过少,会出现编译错误或运行错误。在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT。当一个信号被发射时,与其关联的槽函数通常被立即执行,就像正常调用一个函数一样。只有当信号关联的所有槽函数执行完毕后,才会执行发射信号处后面的代码。
边栏推荐
- Kotlin - 协程上下文 CoroutineContext
- MySQL之InnoDB引擎(五)
- 小公司小而美的产品,如何突围?
- 计算机网络常见面试题目总结,含答案
- Typescript asynchronous function promise use
- Shell script basic programming commands
- 安全测试初学体验
- 记一次 .NET 某物管后台服务 卡死分析
- numpy.newaxis
- Strengthen supervision on secret room escape and script killing, and focus on strengthening fire safety and juvenile protection
猜你喜欢
随机推荐
记一次 .NET 某物管后台服务 卡死分析
第一次培训课完美成功(๑•ㅂ•)و*
Using questpdf operation to generate PDF is faster and more efficient!
数字化工厂有哪些关键技术
How to wait for the return results of multiple asynchronous tasks synchronously?
Silent desktop fan chip dltap703sd Jericho
【JVM 系列】JVM 调优
How to build a super interface collaboration platform: count the six weapons of apifox
20220725 tree array introspection
一个开源的网页画板,真的太方便了
three.js 制作地球标注的两种方法
本机号码一键登录原理与应用(荣耀典藏版)
试用了多款报表工具,终于找到了基于.Net 6开发的一个了
一文读懂 Kubernetes的四种服务类型!
破题数据中心绿色可持续发展
消息队列知识点总结
numpy.put()
潘多尼亚精灵 VoxEdit 创作大赛
Cookies and sessions
有点酷,使用 .NET MAUI 探索太空









