LINUX.ORG.RU

Qt, бесконечный цикл в отдельном потоке

 


0

3

Всем привет!)

В проекте есть класс (Engine) с бесконечным циклом, который вынесен в отдельный поток (moveToThread()). В этом цикле эмитируется сигнал, который ловится слотом в другом классе (MainWindow).

То, что объявлено в MainWindow

QThread thread; //thread и cm- объявлен глобально, здесь для простоты
Engine *cm = new Engine;

cm->moveToThread(&thread);
connect(&thread, &QThread::finished, cm, &QObject::deleteLater); 
connect(cm, &Engine::coordinate, this, &MainWindow::moveEngine); 
thread.start();

То, что в Engine

void Engine::workfunction()
{
   while(key == true)
   {
      ...
      emit coordinate(data);
      if(key == false) break;
   }
}

Теперь получается так, что этот сигнал ловится слотом только первый раз. Полазил в интернете, нашел, что «поток занят функцией с бесконечным циклом, и сигналы встают в очередь и не обрабатываются».

Отсюда https://ru.stackoverflow.com/questions/758609/qt-%d0%bd%d0%b5-%d0%b2%d1%8b%d0%b7%d1%8b%d0%b2%d0%b0%d0%b5%d1%82%d1%81%d1%8f-%d1%81%d0%bb%d0%be%d1%82-%d0%b2-%d0%b4%d1%80%d1%83%d0%b3%d0%be%d0%bc-%d0%bf%d0%be%d1%82%d0%be%d0%ba%d0%b5

Пробовал дописать пятым параметром Qt::DirectConnection сначала - во второй, а потом и в первый конект с различными вариациями - не помогает.

Для меня видится две проблемы:

1. Как сделать отзывчивый бесконечный цикл средствами Qt.

2. Как правильно использовать вызовы для потока QThread.

Расскажите, пожалуйста


Не вижу проблемы в коде. Ты уверен, что у тебя цикл продолжает крутиться? Вставь туда вывод в лог.

panter_dsd ★★★★
()

Qt::DirectConnection

Аналогично прямому вызову. Не надо так в многопотоке. Тебе нужен QueuedConnection.

сначала - во второй, а потом и в первый конект

Дописывать нужно в коннект, который соединяет сигнал coordinate. connect сам выставит соединение через очередь, если классы находятся в разных потоках, если соединять после moveToThread.

anonymous
()
Ответ на: комментарий от panter_dsd

Ему не нужно вообще указывать тип коннекта

Ога, я так и написал.

anonymous
()
Ответ на: комментарий от panter_dsd

Простите, товарищи, вы правы, эта часть рабочая. Я сейчас прошелся дебагером, ошибка дальше в моей логике. Тогда, если вам не сложно, проясните ситуацию с отзывчивым бесконечным циклом средствами Qt.

Прочитал про QEventLoop и его метод QEventLoop::processEvents()

Как это должно работать?

Tumyq
() автор топика
Ответ на: комментарий от Tumyq

Лучше это не использовать, но если тебе нужно, то делаешь:

while (...) {
 ........
 QEventLoop::processEvents();
}

И при вызове processEvents произойдет прокрутка ивентлупа, интерфейс не замрет, но твоя операция воооот такая длительная станет.

panter_dsd ★★★★
()
Ответ на: комментарий от panter_dsd

дело в том, что я создаю экземпляр класса(Engine) с бесконечным циклом в конструкторе из другого класса(MainWindow), и MainWindow не успевает создасться, все повисает в Engine. Тут я сделал костыль из QTimer, который запускает цикл через энное количество времени, но в целом, это как-то нехорошо.

То есть мне такой метод должен помочь не при дальнейшей работе, а вначале создания всех объектов, но он не помогает, я так пробовал

Tumyq
() автор топика
Ответ на: комментарий от Tumyq

1. Создавай не в конструкторе, а в методе showEvent (или что-то из них, не помню точно, погугли)

2. Создавай через таймер с нулевым таймаутом, это вполне нормальная практика.

QTimer::singleShot(0, this, &MainWindow::makeEngine);
panter_dsd ★★★★
()
Ответ на: комментарий от panter_dsd

Спасибо, тогда, как говорится «и так сойдет») Спасибо всем за помощь!

Tumyq
() автор топика

В проекте есть класс (Engine) с бесконечным циклом, который вынесен в отдельный поток (moveToThread()). В этом цикле эмитируется сигнал, который ловится слотом в другом классе (MainWindow).
Пробовал дописать пятым параметром Qt::DirectConnection сначала - во второй, а потом и в первый конект с различными вариациями - не помогает.

/0
Попробуйте изучить матчасть, а потом писать свой говнокод... Мне лень разжевывать идиотские ошибки, лишь скажу что корень в том что вы профан и не удосужились изучить даже базовых основ работы с фреймворком.

erfea ★★★★★
()
Ответ на: комментарий от erfea

Да ну вот это примерно то что напишешь начитавшись интернетов. Ты бы лучше гонор поубавил и помог нубасу, он хотя бы пытается разобраться (не исключено что по русским переводам).

anonymous
()

Я прошу прощения, а зачем вообще бесконечный цикл? Может есть возможность обойтись exec() в конце workfunction() и сигналами-слотами?

aiqu6Ait ★★★★
()
Ответ на: комментарий от aiqu6Ait

Насколько понимаю, речь о QThread::exec().

То есть, мне надо поместить функцию в отдельный поток, отлавливать ее окончание сигналом, и снова слотом ее запускать?

Tumyq
() автор топика
14 марта 2019 г.
Ответ на: комментарий от Tumyq

Наверное поздно, но отвечу. Если не ошибаюсь, exec подвешивает процесс/нить и запускает ее по прерываниям. Поэтому закидывай в отдельный поток, запускай exec и по прерываниям будет что-нибудь запускаться.

aiqu6Ait ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.