Qt信号和插槽:权限

Qt signals and slots: permissions

本文关键字:权限 插槽 信号 Qt      更新时间:2023-10-16
SO

上受人尊敬的答案与实际的Qt文档之间存在差异。

我已经阅读了这个问题,我想进一步澄清。谁能确认:

  • 信号总是protected的,因此它只能由类或其任何子类发出。我不确定这是真的;上面的问题显示了支持这一说法的答案。但是Qt文档说: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 关键字毫无用
  • 处发射的信号始终
  • 可用于所有其他类,也就是说,任何其他类可能始终连接到该信号(无论其发射信号的权限如何(。
  • 尽管所有类都可以查看所有信号,但您仍然可以有两个具有相同名称信号的类,因为connect函数将类名作为信号前缀(即 SomeClass::itsSignal (
  • 信号在Qt4中受到保护,但在Qt5中是公开的,因此信息相互矛盾。
  • 插槽是函数,公共/受保护/私有在调用它们时是这样的,当连接到信号时,元对象系统会忽略它。
  • 由于signals被定义为public:,因此在它们前面加上例如私人线索

自:

private:
public: //signals:
    void theSignal();

因此,它没有效果。

  • 所有类都可以连接到任何信号,正确。在这方面,信号是公共 API 的一部分。
  • 具有相同的信号特征不是问题。上下文由指定为发送方的对象定义。

使用旧式连接:

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

信号在这里被指定为字符串(其中没有类名(,但由于appleorange每个只有一个信号changed()并且查找是在 QObject 实例的元对象中完成的,每个类(不是实例(存在一个,它们不能冲突。

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

connect(apple, &Apple::changed, this, &MyReceiver::appleChanged);
这里必须指定

一个函数,因此根据作用域,必须指定一个类名(也许还有命名空间(。由于一个模棱两可的函数名称在C++是无效的,因此无法编译,所以在这里是安全的。

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

#     define signals public

如您所见,信号头文件中使用的宏被定义为公共的。至于显式状态公共,私有,受保护的指令,这些在信号部分中被忽略。先前的 5.0 版本的 QT 将信号定义为受保护。这些仍然可用于使用 SIGNAL() 宏的连接。

插槽宏

#     define slots

定义为空宏,因此可以与以下对象一起使用:

public slots:
private slots:
protected slots:

方法可见性用于直接方法调用,因此不能直接从外部类调用私有/受保护。

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

如果我没记错的话,在Qt的早期版本中,插槽也是自动public的,但是我现在没有找到参考。

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

发射的信号始终

可用于所有其他类,也就是说,任何其他类可能始终连接到该信号(无论其发射信号的权限如何(。

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