首页 > 其他分享 >Qt基础之四:Qt信号与槽机制原理及优缺点

Qt基础之四:Qt信号与槽机制原理及优缺点

时间:2022-11-20 15:06:09浏览次数:57  
标签:Qt 对象 优缺点 参数 信号 之四 连接 函数


信号和插槽用于对象之间的通信。信号和槽机制是Qt的核心特性,可能也是与其他框架提供的特性最大不同的部分。Qt的元对象系统使信号和槽成为可能。

一.简介

在GUI编程中,当我们改变一个控件,通常希望其他控件被通知到。更一般的,我们希望任意对象之间能够通信。例如,如果我们点击了“关闭”按钮,我们希望窗口的close()函数被调用。
其他工具包使用回调来实现这种通信。回调函数是一个指向函数的指针,所以如果你想要一个处理函数通知你一些事件,你可以将一个指向另一个函数(回调函数)的指针传递给处理函数。处理函数然后在适当的时候调用回调函数。但回调可能不太直观,而且在确保回调参数的类型正确性方面可能会遇到问题。

二.信号和槽

在Qt中,我们有一个回调技术的替代方案:我们使用信号和槽。当特定事件发生时发出信号。Qt的小部件有许多预定义的信号,但是我们总是可以子类化小部件,添加一些自定义信号。槽(slots)是响应特定信号(signals)而调用的函数。Qt的小部件有许多预定义的槽,但是通常的做法是子类化控件并自定义槽函数,这样就可以处理感兴趣的信号。
下图为信号与槽的关系图:支持一对多,多对一

Qt基础之四:Qt信号与槽机制原理及优缺点_qt


1.信号和槽机制是类型安全的

信号与槽机制要求信号和槽的参数一致,所谓一致,是参数类型一致。如果不一致,允许的情况是,信号的参数可以比槽函数的参数多,此时槽可以忽略多余参数。由于参数的一致性,所以当使用基于函数指针的语法时,编译器可以帮助我们检测类型是否匹配;基于字符串的信号和槽语法将在运行时检测类型不匹配。

2.信号和槽是松散耦合的

信号和槽是松散耦合的,发出信号的类既不知道也不关心哪个槽接收信号。Qt的信号和槽机制确保,如果您将信号连接到时隙,将在正确的时间使用信号的参数调用该槽。信号和槽可以采用任意数量的任何类型的参数。它们完全是类型安全的。

从QObject或其子类(例如QWidget)继承的所有类都可以包含信号和槽。当对象的状态发生变化时,它们会发出信号,它不知道或不关心是否有任何槽在接收它发出的信号,这足以实现信息封装。

槽可以用于接收信号,但它们也是正常的成员功能。就像一个对象不知道是否有任何其他对象接收到它的信号一样,槽也不知道它是否有任何信号连接到它。这确保了可以使用Qt创建真正独立的组件。

您可以将任意多个信号连接到一个槽,并且可以将信号连接到任意多个槽。甚至可以将一个信号直接连接到另一个信号。(每当发出第一个信号时,这将立即发出第二个信号。)

信号和槽共同构成了强大的组件编程机制。

三.信号(signals)

当对象内部状态以对象的客户端或用户感兴趣的某种方式发生变化时—比如点击、鼠标移动等,对象就会发出信号。信号(signals)都是共有(public)的,可以从任何地方发出,但最好只从该定义信号的类及其子类使用该信号。当信号发出时,通常采用直连方式连接槽函数,这种连接方式会立即执行槽函数,就像普通的函数调用一样。此时信号和槽机制完全独立于任何GUI事件循环。一旦所有的槽都返回,emit语句之后的代码就会执行(同步发送)。当使用队列连接时,情况略有不同;在这种情况下,emit关键字后面的代码将立即继续,槽将稍后执行(异步发送)。如果多个槽连接到一个信号,当信号发出时,槽将按照它们连接的顺序依次执行。信号是由moc(元对象编译器)自动生成的,在build目录中的moc_**文件中。信号永远不能有返回类型(即使用void)。

四.槽(slots)

槽在信号发出时被调用。slot也是C++函数,可以像普通函数一样正常调用,它们唯一的特点是可以连接信号。因为槽函数是普通的成员函数,所以当直接调用时,它们遵循普通的C++规则。与回调相比,信号和槽稍微慢一些,因为它们提供了更大的灵活性,尽管实际应用程序中的差异并不大。一般来说,emit一个连接到一些槽的信号,大约比直接调用非虚函数慢十倍。原因是在定位连接对象、安全遍历所有连接(即检查在发送过程中后续槽函数是否被销毁)等所需的开销。虽然十个非虚函数调用可能听起来很多,但它的开销比任何new或delete操作都要小得多。一旦在后续执行需要new或delete的字符串、vector or list等操作,信号和槽开销只占整个函数调用开销的很小一部分。信号和槽机制的简单性和灵活性是非常值得的,用户甚至不会注意到这些开销。
注意,当定义了signals或slots变量的第三方库与基于qt的应用程序一起编译时,可能会导致编译器警告和错误。要解决这个问题,请#undef有问题的预处理器符号

五.在Qt中使用第三方的Signals和Slots

可以将Qt与第三方信号/槽机制一起使用。你甚至可以在同一项目中使用这两种机制。只需将以下行添加到qmake项目(.pro)文件中。

CONFIG += no_keywords

它告诉Qt不要定义moc关键字signals、slot和emit,因为这些名称将由第三方库使用,例如Boost。然后,要继续使用带有no_keywords标志的Qt信号和时隙,只需将源代码中Qt-moc所使用的关键字替换为相应的Qt宏Q_SIGNALS(或Q_SIGNAL)、Q_SLOTS(或Q-SLOT)和Q_EMIT。
在需要信号发送方信息的情况下,Qt提供了QObject::sender()函数,它返回一个指向发送信号的对象的指针。如下所示:

void MyWidget::on_pushButton_clicked()
{
QPushButton *button = static_cast<QPushButton*>(QObject::sender());
qDebug() << button->text();
}

以上内容参考:​​https://doc.qt.io/qt-5/signalsandslots.html​​​ 总结一下:
1.优点
①类型安全。需要关联的信号槽的签名必须是等同的。即信号的参数类型和参数个数同接受该信号的槽的参数类型和参数个数相同。若信号和槽签名不一致,编译器会报错。
②松散耦合。信号和槽机制减弱了Qt对象的耦合度。发送信号的Qt对象无需知道是那个对象的那个信号槽接收它发出的信号,它只需在适当的时间发送适当的信号即可。Qt可以保证了适当的槽得到了调用,即使关联的对象在运行时被删除。程序也不会奔溃。
③灵活性。一个信号可以关联多个槽,或多个信号关联同一个槽。
2.缺点
速度较慢。与回调函数相比,信号和槽机制运行速度比直接调用非虚函数慢10倍。
原因:
①需要定位接收信号的对象。
②安全地遍历所有关联槽。
③编组、解组传递参数。
④多线程的时候,信号需要排队等待。
然而,与创建对象的new操作及删除对象的delete操作相比,信号和槽的运行代价只是他们很少的一部分。信号和槽机制导致的这点性能损耗,对实时应用程序是可以忽略的。



标签:Qt,对象,优缺点,参数,信号,之四,连接,函数
From: https://blog.51cto.com/u_15753490/5871441

相关文章

  • Qt编写监控Onvif综合示例(支持云台/预置位/抓图/事件订阅等)
    一、功能特点广播搜索设备,支持IPC和NVR,依次返回。可选择不同的网卡IP进行对应网段设备的搜索。依次获取Onvif地址、Media地址、Profile文件、Rtsp地址。可对指定的Pro......
  • Qt基础之九:子线程和GUI交互
    首先要强调的是,子线程是不能直接操作GUI的,关于原因,详见:​​C++面试题之为什么不能多线程直接操作GUI状态​​ Qt提供了三种方式来实现异步操作GUI1.postEvent2.信号和......
  • QT入门之创建新窗口
    1.在QT里面新建1个工程,命名01QT,先生成个空的项目。 2 新建1个源文件C++Source文件,命名main.cpp.main 方法里面这样写//主应用程序QApplicationapp(argc,argv);......
  • nove.19 Qtree1(还是树剖)
    https://www.luogu.com.cn/problem/P4114注意在跳重链的时候链顶要考虑(即不能dfn[top[u]]+1,dfn[u])因为跳完一条重链,u=faz[top[u]],此后再跳就没有考虑到链顶与链顶faz的......
  • Vue XQTypeScriptFramework 使用
    说明XQTypeScriptFramework隶属于XQFramework下JS基础性框架部分XQFramework励志将开发将常用开发语音基础性框架统一汇总,为全站开发使用到的基础语法进行统一,拜......
  • 初学linux笔记 第四章 windows中开发的QT程序适配linux的修改——error: ‘QT_WARNING
    QT程序本身在windows中进行开发的,移植到linux系统上进行编译后发现了不少问题,需要一一进行修改1.系统时间修改首先是系统时间问题SYSTEMTIMEcurrent_date_time;GetLo......
  • qt wps
    1过2过3过icon//设置图标statusTip//状态提示shortcut//设置快捷键1过........................................................................
  • 一招解决错误:This application failed to start because not Qt platform plugin coul
    #遇到的问题最近换了电脑很郁闷,装钉钉装印象笔记打开后,均提示以下这个错误, 错误内容:ThisapplicationfailedtostartbecausenotQtplatformplugincouldbeinit......
  • QT 如何优雅地去掉对话框的问号
    QT对话框的问号是什么?QDialog默认的windowflag中包含了Qt::WindowContextHelpButtonHint,这个flag意思是在窗口上提供"上下文帮助"按钮 使用方式为,调用v......
  • 微前端之四 • Single SPA 的源码实现
    深入了解一个库最好的办法是直接去看源代码,学习作者的设计模式、运行原理、代码风格等。并且动手跑起来,碰到不懂的地方打断点或者打印关键信息,一步一步去琢磨。很多流行库......