Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: nvek от Август 11, 2017, 12:49



Название: Как запихнуть таймер в другой поток?
Отправлено: nvek от Август 11, 2017, 12:49
В конструкторе главной формы я хочу написать следующее:
Код:
QThread* thread = new QThread;
tmr = new QTimer(this);
tmr->moveToThread(thread);

затем там же :
Код:
connect(tmr, &QTimer::timeout, this, &MainForm::updateByTimer, Qt::DirectConnection);
вопрос, будет ли updateByTimer выполняться в другом потоке?


Название: Re: Как запихнуть таймер в другой поток?
Отправлено: lit-uriy от Август 11, 2017, 12:53
Qt::DirectConnection между потоками не работает


Название: Re: Как запихнуть таймер в другой поток?
Отправлено: nvek от Август 11, 2017, 12:55
Сразу видно, что задумка изначально плохая.
Как можно сделать тогда так, чтобы вот та функция, отрабатывала в другом потоке?


Название: Re: Как запихнуть таймер в другой поток?
Отправлено: Old от Август 11, 2017, 12:59
Сразу видно, что задумка изначально плохая.
Как можно сделать тогда так, чтобы вот та функция, отрабатывала в другом потоке?
Таймер будет работать в контексте потока thread, соответственно и слот updateByTimer будет выполняться в его контексте (именно с DirectConnection (автомат применит именно его)).
Только парент уберите из конструктора таймера:
Код
C++ (Qt)
tmr = new QTimer;
 


Название: Re: Как запихнуть таймер в другой поток?
Отправлено: nvek от Август 11, 2017, 13:07
спасибо, даже дебаг подсказал это


Название: Re: Как запихнуть таймер в другой поток?
Отправлено: nvek от Август 11, 2017, 13:11
Поправте меня. Как я понял, если объект класса, унаследованного от QObject, запихнуть в moveToThread,
то все что с ним связано, будет обрабатываться в том потоке, который передал moveToThread?
поясню, если я хочу чтобы переподключение обрабатывалось в другом потоке, можно ли сделать вот так:

Код:
QThread* newThread = new QThread();
myclass = new MyClass();
myclass->moveToThread(newThread);
myclass->reload();

будет ли myclass->reload(); выполняться в другом потоке?


Название: Re: Как запихнуть таймер в другой поток?
Отправлено: Old от Август 11, 2017, 13:24
Так не будет.
А вот если внутри MyClass будет создан и запущен таймер (например), то при его срабатывании слот будет отрабатывать в контексте newThread.


Название: Re: Как запихнуть таймер в другой поток?
Отправлено: ViTech от Август 11, 2017, 14:13
будет ли myclass->reload(); выполняться в другом потоке?

Чтобы myclass->reload() выполнять в другом потоке, можно ещё сделать его слотом или пометить как Q_INVOKABLE. Тогда этот метод можно будет вызывать с помощью QMetaObject::invokeMethod, в том числе асинхронно с Qt::QueuedConnection.


Название: Re: Как запихнуть таймер в другой поток?
Отправлено: nvek от Август 14, 2017, 12:52
а как тогда я изменю интервал таймера?
предположим есть выпадающее меню, в котором заданы интервалы 1, 5, 10. Интервалы таймера
Создаем таймер в MyClass
получаем сигналы тика таймера, соединяем коннектом со своим методом.
и значит чтобы изменить или стопнуть таймер надо вызвать функцию этого класса куда кинуть те числа
MyClass::setInterval(int)

это нормальное решение?


Название: Re: Как запихнуть таймер в другой поток?
Отправлено: Bepec от Август 14, 2017, 15:45
Общение между разными потоками - осуществляйте с помощью сигнал-слотовой системы. Никаких прямых дёрганий.


Название: Re: Как запихнуть таймер в другой поток?
Отправлено: nvek от Август 15, 2017, 06:29
Создал новый класс, унаследовал от QThread в ране стартанул таймер, изич, таймер счелкает в другом потоке, и даже та функция, с которой конекчу, отрабатывает как надо.

как изменить интервал таймера? суть в том, что надо соединять слоты и сигналы с похожими параметрами
вот например:
Код:
autoUpd5Act = new QAction(Resource::OPTIONS_AUTOUPDATE5, this);
autoUpd5Act->setCheckable(true);
autoUpd5Act->setStatusTip(Resource::STATUS_OPTIONS_AUTOUPDATE5);
connect(autoUpd5Act, &QAction::triggered, m_tmr, [&](int) {m_tmr->sl_SetInterval(5000); });
такая ахинея отработает как надо? или же лучше сделать слоты для каждого интервала?


Название: Re: Как запихнуть таймер в другой поток?
Отправлено: Авварон от Август 15, 2017, 11:58
таймер может тикать и в гуях, достаточно, чтобы в потоке жил тот, кто исполняет работу.


Название: Re: Как запихнуть таймер в другой поток?
Отправлено: nvek от Август 16, 2017, 07:49
Суть такая: в есть вьюшка с моделью(куда данные приходят с сервера)
в MainForm