Qt信号和插槽:权限

时间:2013-10-02 02:33:50

标签: c++ qt inheritance signals-slots qt-signals

SO上的尊重答案与实际的Qt文档之间存在差异。

我已阅读this question,我想进一步澄清一下。任何人都可以确认:

  • 信号始终为protected,因此只能由类或其任何子类发出。我不确定这是真的;上面的问题显示了支持这一陈述的答案。但是Qt docs说:Signals are public access functions and can be emitted from anywhere, but we recommend to only emit them from the class that defines the signal and its subclasses.那么它是什么?
  • 插槽只是功能,因此可以是公共的,私人的或受保护的。显然,如果插槽是公共的,外部类能够控制您的类是否将其自身信号之一连接到其自己的插槽之一。但是,SO信息再次与文档不同,后者说:a signal emitted from an instance of an arbitrary class can cause a private slot to be invoked in an instance of an unrelated class.这意味着private不受信号/插槽机制的尊重?
  • 使用signal关键字
  • 时,public,private,protected一词无用
  • 发出的信号始终可供所有其他类使用,也就是说,任何其他类可能始终连接到该信号(无论其发出信号的权限如何)。
  • 尽管所有类都可以查看所有信号,但您仍然可以使用两个具有相同名称信号的类,因为connect函数将类名作为信号前缀(即SomeClass::itsSignal

3 个答案:

答案 0 :(得分:33)

  • 信号在Qt4中受到保护,但在Qt5中是公开的,因此是相互矛盾的信息。
  • 插槽是函数,public / protected / private在调用它们时很荣幸,当连接到信号时,元对象系统会忽略它。
  • 由于signals被定义为public:,所以将它们添加到例如private: public: //signals: void theSignal(); 。私人领导

为:

Apple *apple ... Orange* orange
connect(apple, SIGNAL(changed()), this, SLOT(appleChanged()));
connect(orange, SIGNAL(changed()), this, SLOT(orangeChanged()));

因此没有效果。

  • 所有课程都可以连接到任何信号,正确无误。在这方面,信号是公共API的一部分。
  • 具有相同的信号签名不是问题。上下文由指定为sender的对象定义。

使用旧式连接:

apple

此处将信号指定为字符串(其中没有类名),但orangechanged()每个只有一个信号connect(apple, &Apple::changed, this, &MyReceiver::appleChanged); ,并且在元对象中完成查找对于每个类(非实例)存在一个的QObject实例,它们不会发生冲突。

带编译时检查的Qt 5版本:

{{1}}

这里必须指定一个函数,因此根据范围,必须指定一个类名(可能还有名称空间)。由于模糊的函数名称不是有效的C ++,因此无法编译,所以这里安全。

答案 1 :(得分:4)

看看qobjectdefs.h(QT5.0 +)。在那里定义了moc宏

#     define signals public

正如您所看到的,信号头文件中使用的宏被定义为public。至于显式statet public,private,protected指令,这些指令在信号部分被忽略。之前5.0版本的QT将信号定义为受保护。那些仍然可以使用SIGNAL()宏进行连接。

插槽宏

#     define slots

被定义为空宏,因此可以与:

一起使用
public slots:
private slots:
protected slots:

方法可见性用于直接方法调用,因此不能直接从外部类调用private / protected。

使用a connect语句仍然可以独立于可见性。这是预期的行为,并在moc生成的代码中实现。

如果我在早期版本的Qt中记得正确,那么一个插槽也会自动public,但我现在没有找到它的参考。

任何其他类都可以连接到来自外部类的信号,只要在类中给出Q_OBJECT宏并且已知外部类(包括头部)。由于信号是按类定义的,因此在不同的类中使用相同的信号是完全合法的。这也很方便,例如在所有类中都有一个信号sendInfo(QString)使它更容易记忆。 Q_OBJECT宏使moc创建将信号连接到独立于可见性的插槽所需的代码。

答案 2 :(得分:0)

  

发出的信号始终可供所有其他类使用,也就是说,任何其他类都可以始终连接到该信号(无论其发出信号的权限如何)。

在Qt5中,这不一定是真的。可以使用QPrivateSignal作为最终参数来定义信号,在这种情况下,只有声明信号的对象才能连接到它。

相关问题