【问题标题】:How do I forward a signal to private signal?如何将信号转发到私有信号?
【发布时间】:2020-09-28 20:05:28
【问题描述】:

假设我有以下课程:

class Example : public QObject {
    Q_OBJECT
public:
    explicit Example(QObject * parent = nullptr);
    void example();

signals:
    void publicSignal();
    void privateSignal(QPrivateSignal);
};

privateSignals 使用QPrivateSignal,因此只能由各自的类发出。由于 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),
         ^

有什么方法可以在信号类中使用私有信号作为connect 的目的地?

【问题讨论】:

    标签: c++ qt qt5 signals-slots


    【解决方案1】:

    不幸的是,没有一个小帮手。 Qt 的自动QPrivateSignal 过滤器从其connect 语法中的信号中过滤不移植到它的槽参数。因此,您需要为您的Example 提供一个 lambda:

    connect(other, &SimilarExampleClass::publicSignal, this, [this](){
        emit privateSignal({});
    });
    

    【讨论】:

      【解决方案2】:

      老式信号/槽形式确实适用于私有信号:

      connect(other, SIGNAL(publicSignal()), this, SIGNAL(privateSignal()));

      我在尝试连接到 QTimer 的信号超时时偶然发现了这个问题,至少从 Qt5.9 开始这是一个私有信号

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-08
        • 1970-01-01
        • 2018-05-14
        • 2012-07-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多