Я не звоню exec()
в моем коде, но timer
и QUdpSocket
хорошо работает. exec()
используемый для ожидания event
продолжаться?
ОБНОВЛЕНИЕ: timer
работал, потому что я не звонил moveToThread(this)
на QThread
, который означал QThread
была на самом деле все еще часть main thread
. Что касается QUdpSocket
хорошо я использующий опрос functions
. Таким образом, это не должно было работать с signals
.
ПОДСКАЗКА: если необходимо сделать init
материал, который требует event loop
в Вашем QThread
, Вы можете delay
вызов moveToThread
пока Вам не нужно signals
больше, это практично, когда программа загружается. Вы также не должны называть его в конструкторе (Вы могли назвать его внутри run()
например), просто скопируйте this QThread
указатель на переменную и делает call
позже/в другом месте использование указателя.
Чтобы действительно использовать свой поток вместо цикла выполнения QApplication, вы должны вызвать moveToThread(this)
в конструкторе потока И поместить цикл выполнения в защищенный run()
метод вашего производного класса QThread.
Отдельный цикл выполнения потока предотвращает загромождение цикла QApplication сигналами и слотами, не связанными с IUI, и, следовательно, задержку выполнения слота, например, нажатия кнопки, что приводит к "запаздыванию" вашего приложения.
Примечание: Обычно вы всегда подкласс QThread, смотрите Qt doc для дополнительной информации
Edit: Qt doc неверен, читайте эту тему https://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/
Ваш таймер и сокет, вероятно, используют основной цикл событий, который запускается, когда вы вызываете QCoreApplication :: exec ()
. Хотя я уверен, что для запуска цикла обработки событий внутри потока есть веская причина, я не могу ее придумать.
В документации QThread говорится:
Каждый QThread может иметь свой собственный цикл обработки событий. Вы можете запустить цикл обработки событий, вызвав exec (); вы можете остановить его, вызвав exit () или quit (). Наличие цикла событий в потоке позволяет подключать сигналы от других потоков к слотам в этом потоке, используя механизм, называемый подключениями в очереди. Это также позволяет использовать в потоке классы, которым требуется цикл обработки событий, такие как QTimer и QTcpSocket. Обратите внимание, однако, что невозможно использовать какие-либо классы виджетов в потоке.
Без цикла событий можно генерировать сигналы, которые обрабатываются потоком графического интерфейса пользователя или другим потоком, содержащим цикл событий.Это означает, что поток должен иметь цикл обработки событий, чтобы его слоты были эффективными. Согласно документации выше, некоторые классы, такие как QTimer , требуют запущенного цикла событий, для которого вы должны вызвать QThread :: exec ()
. Другие классы, такие как QTCPSocket , могут работать с циклом событий или без него, в зависимости от используемых функций. В документации по классам должны быть указаны требования, предъявляемые к ним.