Класс QSignalSpy
Класс QSignalSpy позволяет интроспекцию выдачи сигнала. Подробнее...
| Заголовок: | #include <QSignalSpy> |
| CMake: | find_package(Qt6 COMPONENTS Test REQUIRED) target_link_libraries(mytarget PRIVATE Qt6::Test) |
| qmake: | QT += testlib |
| Наследует: | QObject и QList |
Открытые функции
| QSignalSpy(const QObject *obj, const QMetaMethod &signal) | |
| QSignalSpy(const QObject *object, PointerToMemberFunction signal) | |
| QSignalSpy(const QObject *object, const char *signal) | |
| bool | isValid() const |
| QByteArray | signal() const |
| bool | wait(int timeout = 5000) |
Подробное описание
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);
Примечание: Нестандартные типы данных необходимо зарегистрировать, используя функцию qRegisterMetaType(), перед созданием объекта QSignalSpy. Например:
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().
Документация по функциям-членам
[since 5.14] QSignalSpy::QSignalSpy(const QObject *obj, const QMetaMethod &signal)
Создаёт новый QSignalSpy, который прослушивает выдачи сигнала signal от объекта QObject obj. Если 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);
} Эта функция была добавлена в Qt 5.14.
[since 5.4] template <typename PointerToMemberFunction> QSignalSpy::QSignalSpy(const QObject *object, PointerToMemberFunction signal)
Создаёт новый QSignalSpy, который прослушивает выдачи сигнала signal от объекта QObject object. Если QSignalSpy не может прослушать корректный сигнал (например, потому что object является nullptr или signal не обозначает допустимого сигнала object), будет выведено сообщение об ошибке с помощью qWarning(), а последующие вызовы isValid() вернут false.
Пример:
QSignalSpy spy(myPushButton, &QPushButton::clicked);
Эта функция была добавлена в Qt 5.4.
QSignalSpy::QSignalSpy(const QObject *object, const char *signal)
Создаёт новый QSignalSpy, который прослушивает выдачи сигнала signal от объекта QObject object. Если QSignalSpy не может прослушать корректный сигнал (например, потому что object является nullptr или signal не обозначает допустимого сигнала object), будет выведено сообщение об ошибке с помощью qWarning(), а последующие вызовы isValid() вернут false.
Пример:
QSignalSpy spy(myPushButton, SIGNAL(clicked(bool)));
bool QSignalSpy::isValid() const
Возвращает true если шпион сигнала подключен к корректным сигналу, в противном случае false.
QByteArray QSignalSpy::signal() const
Возвращает нормализованный сигнал, к которому подключён шпион.
[since 5.0] bool QSignalSpy::wait(int timeout = 5000)
Запускает цикл обработки событий, который выполняется до получения заданного сигнала. Опционально цикл обработки событий может возвращаться раньше по истечении timeout (в миллисекундах).
Возвращает true если сигнал был выдан как минимум один раз в течение timeout миллисекунд, в противном случае возвращает false.
Пример:
QVERIFY(spy.wait(1000));
Эта функция была добавлена в Qt 5.0.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.0/qsignalspy.html