本页内容

QSignalSpy Class

QSignalSpy 类支持对信号发射进行内省。更多内容...

头文件: #include <QSignalSpy>
CMake: find_package(Qt6 REQUIRED COMPONENTS Test)
target_link_libraries(mytarget PRIVATE Qt6::Test)
qmake: QT += testlib
继承自: QList

公共函数

QSignalSpy(const QObject *object, PointerToMemberFunction signal)
QSignalSpy(const QObject *obj, QMetaMethod signal)
QSignalSpy(const QObject *object, const char *signal)
~QSignalSpy()
bool isValid() const
QByteArray signal() const
bool wait(int timeout)
(since 6.6) bool wait(std::chrono::milliseconds timeout = std::chrono::seconds{5})

详细说明

QSignalSpy 可以连接到任何对象的任何信号,并记录该信号的发射。QSignalSpy 本身是一个由 `QVariant ` 列表组成的列表。信号的每次发射都会向该列表追加一个项,其中包含该信号的参数。

以下示例记录了QCheckBox 对象的clicked() 信号的所有发射情况:

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()。

成员函数文档

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

创建一个新的 QSignalSpy,用于监听来自QObject object 的signal 信号的发出。如果 QSignalSpy 无法监听有效的信号(例如,因为object 属于nullptr 情况,或者signal 未表示object 的有效信号),则会通过qWarning() 输出一条说明性的警告消息,且后续对isValid() 的调用将返回 false。

示例:

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

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

创建一个新的 QSignalSpy,用于监听来自QObject obj 的signal 信号的发出。如果 QSignalSpy 无法监听有效的信号(例如,因为obj 属于nullptr 情况,或者signal 未表示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);
}

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

创建一个新的 QSignalSpy,用于监听来自QObject object 的signal 信号的发出。如果 QSignalSpy 无法监听到有效的信号(例如,因为object 属于nullptr 情况,或者signal 未表示object 的有效信号),则会通过qWarning() 输出一条说明性警告消息,且后续对isValid() 的调用将返回 false。

示例:

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

[noexcept] QSignalSpy::~QSignalSpy()

析构函数。

[noexcept] 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 。

[since 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 中引入。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.