如何将信号转发到私有信号?
How do I forward a signal to private signal?
假设我有以下 class:
class Example : public QObject {
Q_OBJECT
public:
explicit Example(QObject * parent = nullptr);
void example();
signals:
void publicSignal();
void privateSignal(QPrivateSignal);
};
privateSignal
使用 QPrivateSignal
,因此只能由相应的 class 发出。由于 moc 编译器从签名中删除了 QPrivateSignal
,我可以像往常一样使用 connect
:
Example * foo = new Example(this);
Example * bar = new Example(this);
connect(foo, &Example::publicSignal, bar, &Example::example); // works fine, signatures fit
connect(foo, &Example::privateSignal, bar, &Example::example); // works fine, QPrivateSignal not part of signal
我可以轻松地将两种信号变体转发到 publicSignal
变体:
connect(foo, &Example::publicSignal, bar, &Example::publicSignal); // forward foo's signals to bar
connect(foo, &Example::privateSignal, bar, &Example::publicSignal); // forward foo's private signals to bar
即使在 Example's
构造函数中,私有信号显然是不可能的:
Example::Example(QObject * parent) : QObject(this) {
// Suppose that SimilarExampleClass looks the same but does not recurse
SimilarExampleClass * other = new SimilarExampleClass(this);
// this does not compile either
connect(other, &SimilarExampleClass::publicSignal, this, &Example::privateSignal);
}
两种情况都会导致以下错误:
$QTHOME/include/QtCore/qobject.h: In instantiation of ‘static QMetaObject::Connection QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const typename QtPrivate::FunctionPointer<Func2>::Object*, Func2, Qt::ConnectionType) [with Func1 = void (SimilarExampleClass::*)(); Func2 = void (Example::*)(Example::QPrivateSignal); typename QtPrivate::FunctionPointer<Func>::Object = SimilarExampleClass; typename QtPrivate::FunctionPointer<Func2>::Object = Example]’:
example.cpp:107:89: required from here
$QTHOME/include/QtCore/qobject.h:239:9: error: static assertion failed: The slot requires more arguments than the signal provides.
Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
^
$QTHOME/include/QtCore/qobject.h:241:9: error: static assertion failed: Signal and slot arguments are not compatible.
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
^
...
$QTHOME/include/QtCore/qobject.h: In instantiation of ‘static QMetaObject::Connection QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const typename QtPrivate::FunctionPointer<Func2>::Object*, Func2, Qt::ConnectionType) [with Func1 = void (SimilarExampleClass::*)(SimilarExampleClass::QPrivateSignal); Func2 = void (Example::*)(Example::QPrivateSignal); typename QtPrivate::FunctionPointer<Func>::Object = SimilarExampleClass; typename QtPrivate::FunctionPointer<Func2>::Object = Example]’:
example.cpp:108:90: required from here
$QTHOME/include/QtCore/qobject.h:241:9: error: static assertion failed: Signal and slot arguments are not compatible.
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
^
有什么方法可以在信号的 class 中使用私人信号作为 connect
的目的地?
可惜不是没有小帮手。 Qt 在其 connect
语法中从信号自动 QPrivateSignal
过滤器不会移植到其槽参数。因此,您的 Example
:
需要一个 lambda
connect(other, &SimilarExampleClass::publicSignal, this, [this](){
emit privateSignal({});
});
旧学校 signal/slot 形式确实适用于私人信号:
connect(other, SIGNAL(publicSignal()), this, SIGNAL(privateSignal()));
我在尝试连接到 QTimer 的信号超时时偶然发现了这个问题,至少从 Qt5.9 开始它是一个私有信号
假设我有以下 class:
class Example : public QObject {
Q_OBJECT
public:
explicit Example(QObject * parent = nullptr);
void example();
signals:
void publicSignal();
void privateSignal(QPrivateSignal);
};
privateSignal
使用 QPrivateSignal
,因此只能由相应的 class 发出。由于 moc 编译器从签名中删除了 QPrivateSignal
,我可以像往常一样使用 connect
:
Example * foo = new Example(this);
Example * bar = new Example(this);
connect(foo, &Example::publicSignal, bar, &Example::example); // works fine, signatures fit
connect(foo, &Example::privateSignal, bar, &Example::example); // works fine, QPrivateSignal not part of signal
我可以轻松地将两种信号变体转发到 publicSignal
变体:
connect(foo, &Example::publicSignal, bar, &Example::publicSignal); // forward foo's signals to bar
connect(foo, &Example::privateSignal, bar, &Example::publicSignal); // forward foo's private signals to bar
即使在 Example's
构造函数中,私有信号显然是不可能的:
Example::Example(QObject * parent) : QObject(this) {
// Suppose that SimilarExampleClass looks the same but does not recurse
SimilarExampleClass * other = new SimilarExampleClass(this);
// this does not compile either
connect(other, &SimilarExampleClass::publicSignal, this, &Example::privateSignal);
}
两种情况都会导致以下错误:
$QTHOME/include/QtCore/qobject.h: In instantiation of ‘static QMetaObject::Connection QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const typename QtPrivate::FunctionPointer<Func2>::Object*, Func2, Qt::ConnectionType) [with Func1 = void (SimilarExampleClass::*)(); Func2 = void (Example::*)(Example::QPrivateSignal); typename QtPrivate::FunctionPointer<Func>::Object = SimilarExampleClass; typename QtPrivate::FunctionPointer<Func2>::Object = Example]’:
example.cpp:107:89: required from here
$QTHOME/include/QtCore/qobject.h:239:9: error: static assertion failed: The slot requires more arguments than the signal provides.
Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
^
$QTHOME/include/QtCore/qobject.h:241:9: error: static assertion failed: Signal and slot arguments are not compatible.
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
^
...
$QTHOME/include/QtCore/qobject.h: In instantiation of ‘static QMetaObject::Connection QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const typename QtPrivate::FunctionPointer<Func2>::Object*, Func2, Qt::ConnectionType) [with Func1 = void (SimilarExampleClass::*)(SimilarExampleClass::QPrivateSignal); Func2 = void (Example::*)(Example::QPrivateSignal); typename QtPrivate::FunctionPointer<Func>::Object = SimilarExampleClass; typename QtPrivate::FunctionPointer<Func2>::Object = Example]’:
example.cpp:108:90: required from here
$QTHOME/include/QtCore/qobject.h:241:9: error: static assertion failed: Signal and slot arguments are not compatible.
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
^
有什么方法可以在信号的 class 中使用私人信号作为 connect
的目的地?
可惜不是没有小帮手。 Qt 在其 connect
语法中从信号自动 QPrivateSignal
过滤器不会移植到其槽参数。因此,您的 Example
:
connect(other, &SimilarExampleClass::publicSignal, this, [this](){
emit privateSignal({});
});
旧学校 signal/slot 形式确实适用于私人信号:
connect(other, SIGNAL(publicSignal()), this, SIGNAL(privateSignal()));
我在尝试连接到 QTimer 的信号超时时偶然发现了这个问题,至少从 Qt5.9 开始它是一个私有信号