Класс SyncThread(абстрактный)
#include <QtCrypto>
Диаграмма кооперации класса QCA::SyncThread:

Публичные функции
| QVariant | call (QObject *obj, const QByteArray &method, const QVariantList &args=QVariantList(), bool *ok=nullptr) |
| void | start () |
| void | stop () |
| SyncThread (QObject *parent=nullptr) | |
| ~SyncThread () override |
Защищённые методы
| virtual void | atEnd ()=0 |
| virtual void | atStart ()=0 |
| void | run () override |
Дружественные функции и классы
| class | Private |
Связанные символы
| (Примечание: данные символы не являются членами класса.) | |
| QCA_EXPORT bool | invokeMethodWithVariants (QObject *obj, const QByteArray &method, const QVariantList &args, QVariant *ret, Qt::ConnectionType type=Qt::AutoConnection) |
| QCA_EXPORT QByteArray | methodReturnType (const QMetaObject *obj, const QByteArray &method, const QList<QByteArray > argTypes) |
Подробное описание
Удобный класс для запуска потока и синхронного взаимодействия с ним.
SyncThread
позволяет легко выполнять обычную практику запуска потока, запуска некоторых объектов в этом потоке,
а затем безопасного взаимодействия с этими объектами. Часто нет необходимости напрямую использовать
примитивы потоков (например, QMutex), в результате чего получается очень чистый многопоточный
код.
Примечание.
С помощью
SyncThread
можно запускать, останавливать и вызывать метод в другом потоке, пока основной поток находится в
спящем режиме. Единственное требование — объявить методы как слоты.
Ниже приведён искусственный пример, где есть объект в другом потоке, который увеличивает счётчик в течение некоторого интервала, используя цикл событий Qt, и предоставляет метод для проверки значения.
Во-первых, объект Counter:
class Counter : public QObject
{
Q_OBJECT
private:
int x;
QTimer timer;
public:
Counter() : timer(this)
{
x = 0;
connect(&timer, &QTimer::timeout, this, &Counter::t_timeout);
}
public slots:
void start(int seconds)
{
timer.setInterval(seconds * 1000);
timer.start();
}
int value() const
{
return x;
}
private Q_SLOTS:
void t_timeout()
{
++x;
}
};
Выглядит как типичный объект, без сюрпризов.
Далее Counter оборачивается SyncThread. Это можно сделать очень просто:
class CounterThread : public SyncThread
{
Q_OBJECT
public:
Counter *counter;
CounterThread(QObject *parent) : SyncThread(parent)
{
counter = 0;
}
~CounterThread()
{
// SyncThread остановит поток при разрушении, но поскольку
// функция atStop() делает ссылки на члены CounterThread,
// нужно завершить работу здесь, прежде чем CounterThread
// разрушится.
stop();
}
protected:
virtual void atStart()
{
counter = new Counter;
}
virtual void atStop()
{
delete counter;
}
};
Затем это можно использовать:
CounterThread *thread = new CounterThread;
// после этого вызова поток запускается, и счётчик готов
thread->start();
// запускается счётчик с интервалом в 1 секунду
thread->call(thread->counter, "start", QVariantList() << 1);
…
// по прошествии некоторого времени проверяется значение
int x = thread->call(thread->counter, "value").toInt();
// завершено
delete thread;
Где-нибудь виден мьютекс? Нет.
Даже без функции
call()
SyncThread
по-прежнему очень полезен для подготовки объектов в другом потоке, для которого затем можно
использовать QObject::connect() и сигналы и слоты, как обычно.
Описание конструкторов и деструктора
SyncThread()
| QCA::SyncThread::SyncThread (QObject * parent = nullptr) |
Стандартный конструктор.
Параметры
| parent | Родительский объект |
~SyncThread()
| QCA::SyncThread::~SyncThread () | override |
Вызывает stop(), а затем уничтожает.
Примечание.
Подклассы должны вызывать stop() в собственном деструкторе.
Описание методов
start()
| void QCA::SyncThread::start () |
Запускает поток, запускает цикл обработки событий потока, а затем вызывает atStart() в потоке.
Эта функция будет блокироваться, пока atStart() не вернётся.
stop()
| void QCA::SyncThread::stop () |
Останавливает цикл обработки событий потока, вызывает atStop() в потоке и инструктирует поток
завершить работу.
Эта функция будет блокироваться, пока поток не завершится.
call()
| QVariant QCA::SyncThread::call (QObject * obj, const QByteArray & method, const QVariantList & args = QVariantList(), bool * ok = nullptr) |
Вызывает слот объекта в потоке.
Эта функция будет блокироваться, пока слот не вернётся.
При вызове возможен сбой, например, если метод не существует.
Аргументы и возвращаемое значение метода используют QVariant. Если метод не имеет возвращаемого
значения (возвращает void), то возвращаемый QVariant будет null.
Параметры
| obj | Объект для вызова метода |
| method | Название метода (без аргументов и скобок) |
| args | Список аргументов для использования при вызове метода |
| ok | Если не 0, здесь хранится true, если вызов завершается успешно, в противном случае здесь хранится false. |
atStart()
| virtual void QCA::SyncThread::atStart () | protected pure virtual |
Нужно переопределить этот метод, чтобы выполнить свою инициализацию.
atEnd()
| virtual void QCA::SyncThread::atEnd () | protected pure virtual |
Нужно переопределить этот метод, чтобы выполнить деинициализацию.
run()
| void QCA::SyncThread::run () | override protected |
Запускает цикл событий и при необходимости вызывает atStart и atStop.
Описание дружественных и связанных символов
methodReturnType()
| QCA_EXPORT QByteArray methodReturnType (const QMetaObject * obj, const QByteArray & method, const QList<QByteArray >argTypes ) | related |
Удобный метод для определения возвращаемого типа метода.
Эта функция определяет тип возвращаемого значения указанного метода. Её можно использовать следующим образом:
class TestClass : public QObject
{
Q_OBJECT
// …
public slots:
QString qstringMethod() { return QString(); };
bool boolMethod( const QString & ) { return true; };
};
QByteArray myTypeName;
TestClass testClass;
QList<QByteArray> argsList; // пустой список, поскольку аргументов нет
myTypeName = QCA::methodReturnType( testClass.metaObject(), QByteArray( "qstringMethod" ), argsList );
// myTypeName — это "QString"
myTypeName = QCA::methodReturnType( testClass.metaObject(), QByteArray( "boolMethod" ), argsList );
// myTypeName — это "", потому что не существует метода с именем "boolMethod" без аргументов
argsList << "QString"; // теперь имеется один аргумент
myTypeName = QCA::methodReturnType( testClass.metaObject(), QByteArray( "boolMethod" ), argsList );
// myTypeName — это "bool"
Имя типа возвращаемого значения метода, возвращающего void, является пустой строкой, а не
«void».
Примечание.
Эта функция обычно не требуется для использования с QCA. При необходимости она предоставляется для использования в коде.
Параметры
| obj | QMetaObject для объекта |
| method | Название метода (без аргументов и скобок) |
| argTypes | Список типов аргументов метода |
Возвращает имя типа, который этот метод вернёт с указанными типами аргументов.
См. также QMetaType для получения дополнительной информации о системе метатипов Qt.
invokeMethodWithVariants()
| QCA_EXPORT bool invokeMethodWithVariants (QObject * obj, const QByteArray & method, const QVariantList & args, QVariant * ret, Qt::ConnectionTypetype = Qt::AutoConnection) | related |
Удобный метод для вызова метода по имени с использованием списка аргументов QVariant.
Её можно использовать следующим образом:
class TestClass : public QObject
{
Q_OBJECT
// …
public slots:
QString qstringMethod() { return QString( "the result" ); };
bool boolMethod( const QString & ) { return true; };
};
TestClass *testClass = new TestClass;
QVariantList args;
QVariant stringRes;
// вызывает testClass->qstringMethod() без аргументов (поскольку args — пустой список)
bool ret = QCA::invokeMethodWithVariants( testClass, QByteArray( "qstringMethod" ), args, &stringRes );
// ret равно true (так как вызов завершился успешно), stringRes.toString() — это строка-«результат»
QVariant boolResult;
QString someString( "not important" );
args << someString;
// вызывает testClass->boolMethod(someString), возвращая результат в boolResult
ret = QCA::invokeMethodWithVariants( testClass1, QByteArray( "boolMethod" ), args, &boolResult );
// ret равно true (поскольку вызов выполнен успешно), boolResult.toBool() равно true.
Параметры
| obj | Объект для вызова метода |
| method | Название метода (без аргументов и скобок) |
| args | Список аргументов для использования при вызове метода |
| ret | Возвращаемое значение метода (не изменяется, если вызов не удался) |
| type | Тип используемого подключения |
Возвращает true, если вызов успешен, иначе false.