Класс 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
.