QSignalSpy 类

QSignalSpy 类允许对信号发射进行内省。 更多...

头文件 #include <QSignalSpy>
CMakefind_package(Qt6 REQUIRED COMPONENTS Test)
target_link_libraries(mytarget PRIVATE Qt6::Test)
qmakeQT += testlib
继承自 QObjectQList

公开函数

QSignalSpy(const QObject *object, const char *signal)
QSignalSpy(const QObject *object, PointerToMemberFunction signal)
QSignalSpy(const QObject *obj, const QMetaMethod &signal)
boolisValid() const
QByteArraysignal() const
boolwait(int timeout)
(自 6.6) boolwait(std::chrono::milliseconds timeout = std::chrono::seconds{5})

详细信息

QSignalSpy 可以连接到任何对象的任何信号并记录其发射。 QSignalSpy 本身是一个包含 QVariant 列表的列表。每个信号的发射都会将该列表的一个条目添加到其中,包含信号的参数。

以下示例记录了 clicked() 信号的信号发射,该信号属于一个 QCheckBox

QCheckBox *box = ...;
QSignalSpy spy(box, SIGNAL(clicked(bool)));

// do something that triggers the signal
box->animateClick();

QCOMPARE(spy.count(), 1); // make sure the signal was emitted exactly one time
QList<QVariant> arguments = spy.takeFirst(); // take the first signal

QVERIFY(arguments.at(0).toBool() == true); // verify the first argument

spy.takeFirst() 返回第一个发射的信号的参数,作为一个 QVariant 对象的列表。 clicked() 信号有一个单个的 bool 参数,它作为参数列表中的第一个条目存储。

以下示例从自定义对象中捕获信号

QSignalSpy spy(myCustomObject, SIGNAL(mySignal(int,QString,double)));

myCustomObject->doSomething(); // trigger emission of the signal

QList<QVariant> arguments = spy.takeFirst();
QVERIFY(arguments.at(0).typeId() == QMetaType::Int);
QVERIFY(arguments.at(1).typeId() == QMetaType::QString);
QVERIFY(arguments.at(2).typeId() == QMetaType::Double);

请注意: 在您可以创建 QSignalSpy 之前,需要使用 qRegisterMetaType() 函数注册非标准数据类型。例如

qRegisterMetaType<SomeStruct>();
QSignalSpy spy(&model, SIGNAL(whatever(SomeStruct)));

要检索实例,可以使用 qvariant_cast

// get the first argument from the first received signal:
SomeStruct result = qvariant_cast<SomeStruct>(spy.at(0).at(0));

验证信号发射

QSignalSpy 类提供了一种优雅的机制来捕获对象触发的信号列表。但是,您应该在构造之后验证其有效性。构造函数执行多项合理性检查,例如,检查要监视的信号实际上是否存在。为了使测试失败的诊断更容易,应在进一步进行测试之前调用 QVERIFY(spy.isValid()) 来检查这些检查的结果。

另请参阅 QVERIFY

成员函数文档

[显式] QSignalSpy::QSignalSpy(const QObject *object, const char *signal)

构建一个新的 QSignalSpy 以监听QObject 对象的 signal 信号发射。如果 QSignalSpy 无法监听有效信号(例如,因为 objectnullptrsignal 不表示 object 的有效信号),将使用 qWarning() 输出解释性警告消息,并且后续对 isValid() 的调用将返回 false。

示例

QSignalSpy spy(myPushButton, SIGNAL(clicked(bool)));

template <typename PointerToMemberFunction> QSignalSpy::QSignalSpy(const QObject *object, PointerToMemberFunction signal)

构建一个新的 QSignalSpy 以监听QObject 对象的 signal 信号发射。如果 QSignalSpy 无法监听有效信号(例如,因为 objectnullptrsignal 不表示 object 的有效信号),将使用 qWarning() 输出解释性警告消息,并且后续对 isValid() 的调用将返回 false。

示例

QSignalSpy spy(myPushButton, &QPushButton::clicked);

QSignalSpy::QSignalSpy(const QObject *obj, const QMetaMethod &signal)

构建一个新的 QSignalSpy 以监听QObject 对象的 signal 信号发射。如果 QSignalSpy 无法监听有效信号(例如,因为 objnullptrsignal 不表示 obj 的有效信号),将使用 qWarning() 输出解释性警告消息,并且后续对 isValid() 的调用将返回 false。

当在测试中大量使用 Qt 的元对象系统时,此构造函数使用方便。

基本使用示例

QObject object;
auto mo = object.metaObject();
auto signalIndex = mo->indexOfSignal("objectNameChanged(QString)");
auto signal = mo->method(signalIndex);

QSignalSpy spy(&object, signal);
object.setObjectName("A new object name");
QCOMPARE(spy.count(), 1);

假设我们需要检查表示最小和最大尺寸的QWindow 类的所有属性是否可以正确写入。下面的示例演示了一种方法

void tst_QWindow::writeMinMaxDimensionalProps_data()
    QTest::addColumn<int>("propertyIndex");

    // Collect all relevant properties
    static const auto mo = QWindow::staticMetaObject;
    for (int i = mo.propertyOffset(); i < mo.propertyCount(); ++i) {
        auto property = mo.property(i);

        // ...that have type int
        if (property.type() == QVariant::Int) {
            static const QRegularExpression re("^minimum|maximum");
            const auto name = property.name();

            // ...and start with "minimum" or "maximum"
            if (re.match(name).hasMatch()) {
                QTest::addRow("%s", name) << i;
            }
        }
    }
}

void tst_QWindow::writeMinMaxDimensionalProps()
{
    QFETCH(int, propertyIndex);

    auto property = QWindow::staticMetaObject.property(propertyIndex);
    QVERIFY(property.isWritable());
    QVERIFY(property.hasNotifySignal());

    QWindow window;
    QSignalSpy spy(&window, property.notifySignal());

    QVERIFY(property.write(&window, 42));
    QCOMPARE(spy.count(), 1);
}

bool QSignalSpy::isValid() const

如果信号监听器监听到有效信号,则返回 true,否则返回 false。

QByteArray QSignalSpy::signal() const

返回当今监听器正在监听的标准化信号。

bool QSignalSpy::wait(int timeout)

这是一个重载函数,与将 timeout 传递给 chrono 重载等效

wait(std::chrono::milliseconds{timeout});

如果在 timeout 期间至少发射了一次信号,则返回 true,否则返回 false

[自 6.6] bool QSignalSpy::wait(std::chrono::milliseconds timeout = std::chrono::seconds{5})

启动一个事件循环,直到接收到指定的信号或 timeout 过期,以先发生者为准。

timeout 是任何有效的 std::chrono::duration(std::chrono::seconds, std::chrono::milliseconds 等)。

如果在 timeout 期间至少发射了一次信号,则返回 true,否则返回 false

示例

using namespace std::chrono_literals;
QSignalSpy spy(object, signal);
spy.wait(2s);

此功能是在 Qt 6.6 中引入的。

© 2024 Qt公司有限公司。此处包含的文档贡献为各自所有者的版权。提供的文档受免费软件基金会发布的GNU自由文档许可协议(版本1.3)的条款约束。GNU自由文档许可协议1.3版本。Qt及其相关标志是芬兰以及世界其他国家的Qt公司有限公司的商标。所有其他商标均属于各自所有者。