2014-11-06 81 views
0

我正在经历一个Qt教程here,当我遇到这个下面的代码段传来:Qt类中的插槽和信号是什么意思?

#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

@Cupidvogel:呵呵,我错过了一个链接。所以,你最好再次阅读该文档......这是你应该清楚理解的Qt基础知识。官方文件对此很清楚。 – zaufi 2014-11-06 22:41:27

+0

看起来像。巴里,你最好关闭这个问题吗? – SexyBeast 2014-11-06 22:41:45

+0

它需要3个更接近的选票。 – JBL 2014-11-06 22:42:33

回答

3

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

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

通常使用的隐喻是一个电子表格。电子表格具有观察源单元格的单元格 。当源单元格更改时,将从事件更新依赖单元格 。

不差Wikipedia


解释由于Qt的基本发明了你真正看到你在你的问题发表的文章这将是最好的概念。

特别:

信号

信号由物体发出时,其内部状态在某种程度上可能是有趣的对象的客户或者老板发生了变化 。 只有定义信号及其子类的类才可以发出信号 。

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

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

信号由moc自动生成,并且不得在.cpp文件中实现 。它们不能有返回类型(即 使用void)。

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

槽孔

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

由于插槽是正常的成员函数,因此它们在直接调用时遵循正常的C++ 规则。但是,作为插槽,可以通过 连接,通过 任意组件调用它们,而不管其访问级别如何。这意味着从任意类的实例发出的信号可以导致在不相关类的实例 中调用专用插槽。

您也可以将插槽定义为虚拟的,我们已经发现在实践中很有用 。

与回调相比,信号和时隙稍慢,因为它们提供的灵活性增加了 ,但实际应用的差异并不显着。一般来说,发出一个信号 连接到某些插槽,大约比 直接调用接收器慢十倍,并且带有非虚函数调用。此 是定位连接对象所需的开销,以安全地对所有连接进行迭代(即,检查后续接收器 在发射期间未被破坏),并且以通用方式编组任何 参数。虽然十个非虚函数调用 可能听起来很多,但它比任何新操作或删除操作都要少得多。只要您执行字符串,矢量或列表操作,幕后操作需要新增或删除,则信号和插槽开销只负责完成函数调用成本的非常小的比例。

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

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