QSignalSpy Class

QSignalSpyクラスは、シグナル発信のイントロスペクションを可能にします。詳細...

Header: #include <QSignalSpy>
CMake: find_package(Qt6 REQUIRED COMPONENTS Test)
target_link_libraries(mytarget PRIVATE Qt6::Test)
qmake: QT += testlib
Inherits: 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 のメタオブジェクトシステムがテストで多用される場合に便利です。

基本的な使用例です:

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 で導入されました。

©2024 The Qt Company Ltd. 本文書に含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。