Название: QTimer, QThread Отправлено: Bhted от Февраль 20, 2015, 13:14 Нужен таймер, который будет работать в отдельном потоке приложения и после определённого числа переполнений останавливаться. Почему таймер в отдельном потоке? У меня в приложении есть ещё события, и пока они отрабатывают сигналы от таймер выстраиваются в очередь и потом одной пачкой отрабатывают, что мне не подходит. А не подходит, потому что таймер при переполнении рисует разные положения стрелочного индикатора. Визуально стрелка из крайнего положения сразу дёргается в нуль, без плавного движения.
Вот нашёл в сети код, чтобы таймер работал в отдельном потоке. Тут как-то можно из потока сказать таймеру стоп? worker.h Код:
worker.cpp Код: #include "worker.h" mainwindow.h Код: #include <QMainWindow> mainwindow.cpp Код: ... Название: Re: QTimer, QThread Отправлено: Fregloin от Февраль 20, 2015, 15:06 что мешает запихнуть таймер в Worker и общаться посредством сигналов и слотов?
Название: Re: QTimer, QThread Отправлено: Bhted от Февраль 20, 2015, 15:26 Я тогда получу "timers cannot be stopped from another thread"
Вот как я делал: worker.h Код: class Worker : public QObject worker.cpp Код: Worker::Worker() mainwindow.cpp Код: //------------------------------------------------------------------------------ Название: Re: QTimer, QThread Отправлено: Пантер от Февраль 20, 2015, 15:29 Работай через сигналы/слоты или инвокМетод, а не прямыми вызовами методов.
Название: Re: QTimer, QThread Отправлено: Bhted от Февраль 20, 2015, 15:50 Работай через сигналы/слоты или инвокМетод, а не прямыми вызовами методов. А конкретней можете сказать? Я вроде через сигналы/слоты работаю. Когда надо остановить таймер, посылаю сигнал emit stopTimer(), который связан со слотом stop() и вот тогда я и получаю "timers cannot be stopped from another thread".Зато на прямой вызов worker.start(), который делает timer.start(1000), он почему-то не ругается, что стартовать не хочет. Название: Re: QTimer, QThread Отправлено: Пантер от Февраль 20, 2015, 15:52 Код
Название: Re: QTimer, QThread Отправлено: Igors от Февраль 20, 2015, 15:58 Нужен таймер, который будет работать в отдельном потоке приложения и после определённого числа переполнений останавливаться. Почему таймер в отдельном потоке? У меня в приложении есть ещё события, и пока они отрабатывают сигналы от таймер выстраиваются в очередь и потом одной пачкой отрабатывают, что мне не подходит. А не подходит, потому что таймер при переполнении рисует разные положения стрелочного индикатора. Визуально стрелка из крайнего положения сразу дёргается в нуль, без плавного движения. Насчет "пачки событий от таймера" это Вы загнули, там одно событие. Ну ладно, допустим вынесли как-то таймер в поток и тогда получаете от него события "по расписанию". А толку? Ведь рисовать "стрелочный индикатор" можно только в главной нитке которая забита др событиями. Поэтому лучше использовать вторичный цикл processEvents Название: Re: QTimer, QThread Отправлено: Bhted от Февраль 20, 2015, 16:15 Код
Цитировать Насчет "пачки событий от таймера" это Вы загнули, там одно событие. Ну ладно, допустим вынесли как-то таймер в поток и тогда получаете от него события "по расписанию". А толку? Ведь рисовать "стрелочный индикатор" можно только в главной нитке которая забита др событиями. Поэтому лучше использовать вторичный цикл processEvents Ну, там таймер приконнекчен через Qt::QueuedConnection, поэтому я решил, что из-за этого там будет сразу несколько событий, также по индикатору это видно.Цитировать Поэтому лучше использовать вторичный цикл processEvents Да вот когда я вызывал QApplication::processEvents(), там начинались проблемы... Сейчас ещё раз посмотрю, что там было.Название: Re: QTimer, QThread Отправлено: Пантер от Февраль 20, 2015, 16:18 Как я понял, у тебя идут "тяжелые" вычисления, во время которых ты хочешь крутить индикатор. Если так, то ты не то выносишь в поток - нужно выносить вычисления, а не таймер.
Название: Re: QTimer, QThread Отправлено: Igors от Февраль 20, 2015, 16:39 Да вот когда я вызывал QApplication::processEvents(), там начинались проблемы... Сейчас ещё раз посмотрю, что там было. Насчет processEvents() это я погорячился :) - если в очереди много событий, они и будут извлекаться. Ну а почему бы самому не отслеживать истекшее время и обновлять индикатор синхронно? Часто это выглядит примерно так (псевдокод)Код
Как я понял, у тебя идут "тяжелые" вычисления, во время которых ты хочешь крутить индикатор. Если так, то ты не то выносишь в поток - нужно выносить вычисления, а не таймер. Qt рекомендует так делать потому что до этого делали по-старинке (как выше). Но это не значит что новый способ всегда лучше :)Название: Re: QTimer, QThread Отправлено: Bhted от Февраль 20, 2015, 17:08 У меня много частых событий (каждый 100 мс) от com-порта. С портом работаю через QtSerialPort. Читаю данные через сигнал от порта, сигналы выстраиваются в очередь с помощью Qt::QueuedConnection. Данные мы обрабатываем и строим график и рисуем стрелку. Логика работы стрелки такая: установили заданное значение и за n-секунд стрелка возвращается в исходное положение. Значения, устанавливаемые стрелке, меняются не слишком часто.
График строится отлично при такой интенсивности входных данных. А вот стрелка, повторюсь, мельком устанавливается в заданное положение и сразу в исходное возвращается. Значит, попробую запихать чтение данных из порта и их обработку в отдельный поток. Ну и также попробую "отслеживать истекшее время и обновлять индикатор синхронно". Только счётчик i цикла станет членом класс или статической переменной. В общем, попробую. Суть я уловил. Название: Re: QTimer, QThread Отправлено: Alexu007 от Февраль 22, 2015, 09:57 Для отсчитывания промежутков времени в потоке необязательно прикручивать таймер, в потоке есть функция паузы. В поток можно передавать макс. значение стрелки, и он через фиксированные промежутки времени будет посылать сигналы, по которым можно возвращать стрелку в 0.
Код
|