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 列表。信号的每次发射都会向列表追加一个项目,其中包含信号的参数。

下面的示例记录了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() 以 对象列表的形式返回第一个发射信号的参数。 信号有一个 bool 参数,该参数被存储为参数列表的第一个条目。QVariant clicked()

下面的示例捕获了一个来自自定义对象的信号:

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 objectsignal 发射信号。如果 QSignalSpy 无法监听到有效信号(例如,由于objectnullptr ,或signal 并不表示object 的有效信号),则会使用qWarning() 输出一条解释性警告信息,随后对isValid() 的调用将返回 false。

示例

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

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

构造一个新的 QSignalSpy,用于监听来自QObject objsignal 发射信号。如果 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);
}

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

构造一个新的 QSignalSpy,用于监听来自QObject objectsignal 发射信号。如果 QSignalSpy 无法监听到有效信号(例如,由于objectnullptr ,或signal 并不表示object 的有效信号),则会使用qWarning() 输出一条解释性警告信息,随后对isValid() 的调用将返回 false。

示例

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

[noexcept] QSignalSpy::~QSignalSpy()

毁灭者

[noexcept] bool QSignalSpy::isValid() const

如果信号 spy 监听到有效信号,则返回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::秒、std::chrono::毫秒...等)。

如果信号在timeout 中至少发出过一次,则返回true ,否则返回false

示例:

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

此函数在 Qt 6.6 中引入。

© 2025 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.