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 のリストです。シグナルの各発光は、シグナルの引数を含むリストに1つの項目を追加します。

以下の例では、QCheckBoxclicked() シグナルのすべてのシグナルの放出を記録しています:

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引数が1つあり、これが引数リストの最初のエントリとして格納されます。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)

QObject object からのsignal の放出をリッスンする新しい QSignalSpy を構築する。QSignalSpyが有効なシグナルをリッスンできない場合(例えば、objectnullptr であったり、signalobject の有効なシグナルを表していなかったりする場合)、qWarning() を使用して説明の警告メッセージが出力され、isValid() へのその後の呼び出しは false を返します。

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

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

QObject obj からのsignal の放出をリッスンする新しい QSignalSpy を構築する。QSignalSpyが有効なシグナルをリッスンできない場合(例えば、objnullptr であったり、signalobj の有効なシグナルを表していなかったりする場合)、qWarning() を使って説明の警告メッセージが出力され、isValid() を呼び出すと false が返されます。

このコンストラクタは、Qt のメタオブジェクトシステムが Test で多用される場合に便利です。

基本的な使用例です:

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 クラスのすべてのプロパティが適切に書き込み可能かどうかをチェックする必要があるとします。次の例は、そのアプローチの1つを示しています:

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)

QObject object からのsignal の放出をリッスンする新しい QSignalSpy を構築する。QSignalSpyが有効なシグナルをリッスンできない場合(例えば、objectnullptr であったり、signalobject の有効なシグナルを表していなかったりする場合)、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 ...etc) です。

シグナルが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.