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()
и ниже принадлежат этой теме.
Вы также можете отправлять сигналы в слоты в другом потоке, например, если вы хотите нарисовать виджет (который должен быть сделан в основном потоке) из вашего рабочего потока или аналогичного.