Qt: Правильный ли способ публикации событий в QThread?

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

QThread* myWorkerThread = // ...

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

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

2 ответа

Решение

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

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

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

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

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

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

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

Другие вопросы по тегам