Qt: Правильный ли способ публикации событий в QThread? - PullRequest
13 голосов
/ 02 июня 2011

В моем приложении Qt у меня есть основной поток и рабочий поток. Рабочий поток подклассов QThread и обрабатывает события через customEvent. Это правильный путь для основного потока для отправки событий для обработки рабочим потоком?

QThread* myWorkerThread = // ...

QApplication::instance()->postEvent (myWorkerThread, new MyWorkRequestEvent(/* ... */);

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

Ответы [ 2 ]

15 голосов
/ 02 июня 2011

Ваше понимание правильное и действительно очень не интуитивное :)

Большая часть проблем связана с документацией для QThread, которая предлагает создание подкласса QThread.Хотя Qthread имеет свой собственный цикл событий, в цикле событий QThread будут обрабатываться только события и сигналы для объектов QObject, созданных в методе run () (созданном в этом потоке).

Намного лучше инкапсулировать ваш потоклогика в подклассе QObject, а затем переместить этот объект в экземпляр простого QThread.Затем вы можете связаться с этим объектом QObject, используя сигналы (которые будут правильно поставлены в очередь через границы потоков) или пользовательские события.

В этом похожем вопросе есть несколько ссылок, которые должны помочь.

0 голосов
/ 02 июня 2011

События обрабатываются главным циклом событий, который находится в QApplication или QCoreApplication. Поэтому нет смысла отправлять события на QObjects в других потоках (если только вы не создадите там другой цикл событий, который, я не уверен, возможен).

Вы можете отправлять события из других потоков в ваш основной поток. myWorkerThread в вашем примере принадлежит основному потоку, потому что он создан там. Объекты, созданные вашим рабочим потоком в run() и ниже, принадлежат этому потоку.

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

...