Qt 信号可以是公共的、受保护的还是私有的?我可以创建仅在班级内部可见的内部信号吗?
更新:我有一个带有一些内部信号的类。如何使这些信号对其他类不可见(封装和信息隐藏)?
不,信号不能(轻易)
private
。在 Qt5 及更高版本中它们始终为 public
,并且在 Qt4 及之前版本中始终为 protected
。
从 Qt 5 开始,有一个 hack 来发出信号
private
。有关详细信息,请参阅Nikita 的回答。
常见的方式,例如在kdelibs中看到,是这样的:
Q_SIGNALS:
#ifndef Q_MOC_RUN
private: // don't tell moc, doxygen or kdevelop, but those signals are in fact private
#endif
void somePrivateSignal();
这使得信号成为私有的,即它只能由类本身发出,而不能由其子类发出。为了不让“private:”推翻 Q_SIGNALS(moc 不会将 somePrivateSignal 视为信号),它位于 Q_MOC_RUN 内部,仅在 moc 运行时定义。
编辑: 此方法不适用于 Qt 5 引入的新型连接 (
connect(a, &A::someSignal, b, &B::someSlot)
),因为它们需要可访问信号。
信号在 Qt4 中为
protected
,在 Qt5 中为 public
。在 Qt5 中,您可以通过添加 private
作为最后一个参数来使它们成为 QPrivateSignal
。更多信息:http://woboq.com/blog/how-qt-signals-slots-work-part2-qt5.html
槽是简单的方法,可以是公共的、受保护的或私有的。
正如 Andrei 指出的,信号只是 protected 的重新定义,这意味着它们只能由定义它们的类发出。
如果你想让一个类从另一个类发出信号,你必须向它添加一个公共方法(或槽),如下所示:
void emitTheSignal(...) {
emit theSignal(...);
}
现在您可以使用
Q_SIGNAL
宏和普通的 C++ 访问说明符:
protected:
Q_SIGNAL void myProtectedSignal();
private:
Q_SIGNAL void myPrivateSignal();
Qt 信号是公共的,因为任何对象都可以连接到任何信号。
可以通过在其定义中添加
QPrivateSignal
类型作为最后一个参数来将信号设为私有:
signals:
void mySignal(QPrivateSignal);
QPrivateSignal
是由 QObject
宏在每个 Q_OBJECT
子类中创建的私有结构,因此只能在当前类中创建 QPrivateSignal
对象。
从技术上讲,信号仍然具有公共可见性,但它只能由创建它的类发出。
您可以使用 PIMPL 模式来实现这一点。您的私有信号仅存在于私有实现中。