Qt类中的插槽和信号是什么意思?

时间:2014-11-06 22:33:52

标签: c++ qt oop

当我遇到以下这段代码时,我正在阅读Qt教程here

 #include <QObject>

 class Counter : public QObject
 {
     Q_OBJECT

 public:
     Counter() { m_value = 0; }

     int value() const { return m_value; }

 public slots:
     void setValue(int value);

 signals:
     void valueChanged(int newValue);

 private:
     int m_value;
 };

有人可以向我解释声明中public slotssignals的用法是什么吗?我虽然只有两个,publicprivate。他们叫什么,他们的用途是什么?

1 个答案:

答案 0 :(得分:3)

  

信号和插槽是Qt中引入的语言结构   对象[1]之间的通信使其易于实现   观察者模式,同时避免样板代码。这个概念就是这样   GUI小部件可以发送包含事件信息的信号   其他控件使用称为插槽的特殊功能接收。

     

信号/插槽系统非常适合图形用户的方式   接口设计。类似地,可以使用信号/时隙系统   用于其他非GUI用法,例如异步I / O(包括   插座,管道,串行设备等)事件通知或   将超时事件与适当的对象实例和方法相关联   或功能。它易于使用,没有   需要编写注册/注销/调用代码,   因为Qt的元对象编译器(MOC)自动生成   需要的基础设施。

     

常用的比喻是电子表格。电子表格包含单元格   观察源细胞。当源单元改变时,   依赖单元格从事件中更新。

Wikipedia

解释不错

由于Qt基本上发明了这个概念,你最好真正阅读你在问题中发表的文章。

特别是:

  

信号

     

当内部状态发生变化时,对象会发出信号   以某种方式可能对对象的客户或所有者感兴趣。   只有定义信号的类及其子类才能发出   信号。

     

发出信号时,通常会连接到它的插槽   立即执行,就像正常的函数调用一样。当这个   发生时,信号和插槽机制完全独立于任何   GUI事件循环。执行emit语句后面的代码   所有插槽返回后都会发生。情况略有不同   使用排队连接时有所不同;在这种情况下,代码   跟随emit关键字将立即继续,并插槽   将在稍后执行。

     

如果有多个插槽连接到一个信号,则插槽将是   按照他们连接的顺序依次执行,   当信号发出时。

     

信号由moc自动生成,不得为   在.cpp文件中实现。他们永远不会有退货类型(即   使用void)。

     

关于论点的说明:我们的经验表明信号和插槽   如果他们不使用特殊类型,则更可重复使用。如果   QScrollBar :: valueChanged()是使用特殊类型的   假设的QScrollBar :: Range,它只能连接到插槽   专为QScrollBar设计。连接不同的输入   小部件在一起是不可能的。

  

     

当发射连接到它的信号时,调用一个插槽。插槽是   普通的C ++函数,可以正常调用;他们唯一特别的   功能是信号可以连接到它们。

     

由于插槽是普通的成员函数,因此它们遵循普通的C ++   直接调用时的规则。但是,作为插槽,可以调用它们   任何组件,无论其访问级别如何,都通过信号槽   连接。这意味着从一个实例发出的信号   任意类可以导致在实例中调用私有槽   一个无关的班级。

     

您还可以将插槽定义为虚拟插槽,我们已经找到了   在实践中很有用。

     

与回调相比,信号和插槽稍慢,因为   他们提供的灵活性增加了,尽管差别很大   实际应用是微不足道的。一般来说,发出一个信号   连接到一些插槽,大约慢十倍   使用非虚函数调用直接调用接收器。这个   是安全地定位连接对象所需的开销   迭代所有连接(即检查后续接收器)   在发射期间没有被摧毁),并且任何一个都可以   参数以通用方式。十个非虚函数调用   可能听起来很多,它比任何新的或删除都要少得多   例如,操作。一旦你执行字符串,矢量或   列表操作后面的场景需要新建或删除,   信号和插槽开销只对非常小的负责   完整的函数调用成本的比例。

     

每当您在插槽中进行系统调用时都是如此;要么   间接调用十多个函数。在i586-500上,你可以发射   每秒大约2,000,000个信号连接到一个接收器,或   每秒约1,200,000连接到两个接收器。简单   信号和插槽机制的灵活性非常值得   开销,您的用户甚至不会注意到。

     

请注意,定义称为信号或变量的变量的其他库   在与a一起编译时,插槽可能会导致编译器警告和错误   基于Qt的应用程序。要解决这个问题,请#undef得罪   预处理器符号。