Как объединить собственный цикл сообщений и цикл событий Qt?

У меня есть класс, производный от QThread: class MyClass : public QThread. В методе запуска у меня есть "мой собственный" цикл сообщений:

run() { 
  // exec(); // while not reached    
  while (_runMessageLoop && ...) {
    hr = CallDispatch(.....);
    if (hr== 0) QThread::msleep(100); 
    // QCoreApplication::processEvents(); // Does not work
  }
}

Поскольку exec() не выполняется, у меня нет цикла событий Qt. Очевидно, это приводит к тому, что сигнал/слоты не работают правильно . Есть ли возможность объединить Qt и мой собственный цикл сообщений? Или мне нужен часто срабатывающий таймер, чтобы делать то, что я сделал в своем бесконечном цикле?


person Horst Walter    schedule 24.10.2012    source источник


Ответы (2)


Правильный способ «Qt-wise» - использовать таймер и позволить Qt управлять циклом событий.

Если вам нужно зависеть от внешних вещей, вы можете использовать такие вещи, как QAbstractSocket для отправки событий, когда данные поступают через внешний сокет, например.

person Wes Hardaker    schedule 24.10.2012
comment
И запустить таймер, запускающий частые обновления 100 мс, не проблема? - person Horst Walter; 24.10.2012
comment
Но в более общем плане: лучшая идея — выяснить, что вам нужно делать на основе внешних триггеров, если это вообще возможно, и использовать вместо них эти триггеры. Но являются ли таймеры 100 мс проблемой, вам нужно проверить, поскольку это зависит от того, что вы делаете во время этих 100 мс! - person Wes Hardaker; 24.10.2012
comment
Ваш код выше уже делает это!. Да, но без таймеров. Я был обеспокоен накладными таймерами, которые могут быть задействованы. - person Horst Walter; 24.10.2012
comment
Я не думаю, что накладные расходы таймера будут плохими. Но я бы хотел, чтобы обе реализации были протестированы и измерены, чтобы быть уверенным! - person Wes Hardaker; 25.10.2012
comment
Я изменил свой код на таймеры, CallDispatch теперь инкапсулирован и неоднократно вызывается таймером. Проблемы с сигналом/слотами исчезли, значительных накладных расходов не наблюдаю. Тем не менее, я предполагаю, что это связано с некоторыми незначительными накладными расходами: в качестве особого случая QTimer с тайм-аутом 0 истечет время ожидания, как только все события в очереди событий оконной системы будут обработаны. (QT Doku: doc.qt.digia.com/qt/qtimer.html). Самая большая разница, которую я заметил, связана с тем, что мой Dispatch теперь работает в потоке GUI (правильно?), что значительно упрощает вывод. - person Horst Walter; 25.10.2012
comment
Ну, скорее всего, он и раньше работал в потоке графического интерфейса, если только вы специально не написали многопоточное приложение. И да, он не может обещать вам настоящую задержку в 10 мс между вызовами, потому что это будет слишком сильно зависеть от того, что еще происходит и какие другие события требуют обработки. Но это было верно и в вашем коде выше, так что это действительно не изменение. Я определенно рад слышать, что это работает!!! И спасибо за отчет о том, как хорошо это сработало! - person Wes Hardaker; 26.10.2012

На самом деле это не ответ на правильную реализацию цикла событий, я уверен, что есть способ, но скорее обходной путь:

Запустите поток в обычном режиме, exec() и все остальное, и подключите сигнал запуска к слоту (убедитесь, что он вызывается в правильном потоке), затем поместите туда свой цикл и вызовите processEvents() Qt в этом цикле. Это гарантирует правильную настройку цикла событий Qt.

person hyde    schedule 24.10.2012