27

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信号/插槽机制不尊重吗?
  • signalpublic、private、protected 这些词在使用关键字时没有用处
  • 发出的信号始终可供所有其他类使用,也就是说,任何其他类都可以始终连接到该信号(无论其是否允许发出信号)。
  • 尽管所有类都可以查看所有信号,但您仍然可以有两个具有相同名称的信号的类,因为该connect函数将类名作为信号前缀(即SomeClass::itsSignal
4

3 回答 3

38
  • 信号在 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()));

信号在此处指定为字符串(其中没有类名),但由于每个信号只有一个信号,apple并且查找是在 QObject 实例的元对象中完成的,每个类(而不是实例)存在一个,它们不会发生冲突.orangechanged()

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

connect(apple, &Apple::changed, this, &MyReceiver::appleChanged);

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

于 2013-10-02T06:00:56.827 回答
6

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

#     define signals public

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

插槽宏

#     define slots

被定义为空宏,因此可用于:

public slots:
private slots:
protected slots:

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

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

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

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

于 2013-10-02T05:34:16.777 回答
3

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

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

于 2015-12-10T16:54:46.490 回答