Qt信号与槽机制原理及优缺点要幸福就要奋斗
信号和插槽⽤于对象之间的通信。信号和槽机制是Qt的核⼼特性,可能也是与其他框架提供的特性最⼤不同的部分。Qt的元对象系统使信号和插槽成为可能。
作为⼀个C/C++程序员来说 回调应该属于深⼊⼈⼼的机制了。其他⼯具包使⽤回调来实现这种通信。回调函数是⼀个指向函数的指针,所以如果你想要⼀个处理函数通知你⼀些事件,你可以将⼀个指向另⼀个函数(回调函数)的指针传递给处理函数。处理函数然后在适当的时候调⽤回调函数。但回调可能不太直观,⽽且在确保回调参数的类型正确性⽅⾯可能会遇到问题。
在Qt中,我们有⼀个回调技术的替代⽅案:我们使⽤信号和槽。当特定事件发⽣时发出信号。Qt的⼩部件有许多预定义的信号,但是我们总是可以⼦类化⼩部件,添加⼀些⾃定义信号。槽(slots)是响应特定信号(signals)⽽调⽤的函数。Qt的⼩部件有许多预定义的槽,但是通常的做法是⼦类化控件并⾃定义槽函数,这样就可以处理感兴趣的信号。下图为信号与槽的关系图:⽀持⼀对多,多对⼀。
鞠躬尽瘁拼音
(1)信号和槽位机制是类型安全的:
信号的签名与接收的槽函数签名必须匹配。(事实上,槽函数的签名可能⽐它接收到的信号短,因为它可以忽略额外的参数。)由于签名是兼容的,所以当使⽤基于函数指针的语法时,编译器可以帮助我们检测类型是否匹配。基于字符串的信号和槽语法将在运⾏时检测类型不匹配。
刃打一字是什么字
(2)信号和插槽在软件层是解耦的:
发出信号的类既不知道也不关⼼哪个插槽接收信号。如果你将⼀个信号连接到槽函数,Qt的信号和插槽机制会确保⽴即调⽤携带信号传递过来的的参数的槽函数。信号和插槽可以接受任何类型的任意数量的参数,所以它们是完全类型安全的。
那什么是信号(signals)呢 ?
当object的内部状态以object的客户端或⽤户感兴趣的某种⽅式发⽣变化时⽐如点击、⿏标移动等,object就会发出信号。信号(signals)是公共访问函数,可以从任何地⽅发出,但最好只从该定义信号的类及其⼦类使⽤该信号。当信号发出时,通常采⽤直连⽅式连接槽函数,这种连接⽅式会⽴即执⾏槽函数,就像普通的函数调⽤⼀样。此时信号和槽机制完全独⽴于任何GUI事件循环。⼀旦所有的插槽都返回,emit语句之后的代码就会执⾏(同步发送)。当使⽤队列连接时,情况略有不同;在这种情况下,emit关键字后⾯的代码将⽴即继续,插槽将稍后执⾏(异步发送)。如果多个插槽连接到⼀个信号,当信号发出时,插槽将按照它们连接的顺序依次执⾏。信号是由
moc(元对象编译器)⾃动⽣成的,不能在.cpp⽂件中实现。它们永远不能有返回类型(即使⽤void)。
static QMetaObject::Connection connect(const QObject *nder, const QMetaMethod &signal,const QObject *receiver, const QMetaMethod &method,Qt::C
//以下为⼏种连接⽅式:
enum ConnectionType {
AutoConnection,
DirectConnection,武松人物特点
QueuedConnection,
大钟和小钟
BlockingQueuedConnection,
UniqueConnection = 0x80
};
那什么是槽(slots)函数呢?
slot是普通的c++函数,可以正常调⽤;它们唯⼀的特点是可以连接信号。因为槽函数是普通的成员函数,所以当直接调⽤时,它们遵循普通
的c++规则。然⽽,作为Qt核⼼的机制槽函数,不管其访问级别,通过信号插槽连接,它们可以被任何组件调⽤。这意味着从任意类的实例发出的信号可能导致在不相关类的实例中调⽤私有插槽。与回调相⽐,信号和插槽稍微慢⼀些,因为它们提供了更⼤的灵活性,尽管实际应
⽤程序中的差异并不⼤。⼀般来说,emit⼀个连接到⼀些插槽的信号,⼤约⽐直接调⽤⾮虚函数慢⼗倍。原因是在定位连接对象、安全遍历所有连接(即检查在发送过程中后续槽函数是否被销毁)以及以通⽤⽅式编排任何参数所需的开销。虽然⼗个⾮虚函数调⽤可能听起来很多,
但它的开销⽐任何new或delete操作都要⼩得多。⼀旦在后续执⾏需要new或delete的字符串、vector or list等操作,信号和槽开销只占整
个函数调⽤开销的很⼩⼀部分。当你在槽中执⾏系统调⽤时,情况也是⼀样的;或间接调⽤⼗多个函数。信号和插槽机制的简单性和灵活性是⾮常值得的,⽤户甚⾄不会注意到这些开销。
注意,当与基于qt的应⽤程序⼀起编译时,定义了称为signals或slots的变量的第三⽅库可能会导致编译器警告和错误。要解决这个问
题,#undef + 错误的预处理器符号
在需要信号发送⽅信息的情况下,Qt提供了QObject::nder()函数,它返回⼀个指向发送信号的对象安田村
的指针。⽤法如下:
void MyWidget::on_m_cutPushButton_clicked()
{马拉糕>天道酬勤意思
QPushButton *push = static_cast<QPushButton*>(QObject::nder());
qDebug() << push->text(); //
}