Вопрос

Я не звоню 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 сигналами и слотами, не связанными с пользовательским интерфейсом, и, следовательно, задержку выполнения слота.например, при нажатии кнопки, что приводит к "задержке" вашего приложения.

Примечание:Обычно ты всегда подкласс QThread, см. Qt док для получения дополнительной информации

Редактировать:Qt doc ошибочен, прочтите эту тему https://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/

Другие советы

Ваш таймер и сокет, вероятно, используют основной цикл событий, который запускается при вызове QCoreApplication::exec(). Хотя я уверен, что есть веская причина для запуска цикла событий внутри потока, я не могу придумать ни одной.

В Документация QThread состояния:

Каждый QThread может иметь свой собственный цикл событий.Вы можете запустить цикл событий, вызвав exec();вы можете остановить это, вызвав exit() или quit().Наличие цикла событий в потоке позволяет подключать сигналы из других потоков к слотам в этом потоке, используя механизм, называемый подключениями в очереди.Это также позволяет использовать в потоке классы, для которых требуется цикл событий, такие как QTimer и QTcpSocket.Обратите внимание, однако, что невозможно использовать какие-либо классы виджетов в потоке.

Без цикла событий можно передавать сигналы, которые обрабатываются потоком GUI или другим потоком, содержащим цикл событий.Это подразумевает, что поток должен иметь цикл событий, чтобы его слоты были эффективными.Согласно приведенной выше документации, некоторые классы, такие Qтаймер, требуется запущенный цикл событий , для которого вы должны вызвать QThread::exec().Другие классы, такие как Помощью классов qtcpsocket иметь возможности для запуска с циклом событий или без него, в зависимости от используемых функций.В документации к классам должно быть указано, какие требования к ним предъявляются, если таковые имеются.

Это зависит от ваших программ.Вот один из примеров:

void MyThread::run(){
  Curl * curl = new Curl();
  connect( curl, SIGNAL(OnTransfer(QString)), this, SLOTS(OnTransfer(QString)) );
  connect( curl, SIGNAL(OnDone()), curl, SLOTS(deleteLater()) );
  curl->Download("http://google.com");
  exec(); // this is an event loop in this thread, it will wait until you command quit()
}

void MyThread::OnTransfer(QString data){
  qDebug() << data;
}

Без exec() OnTransfer никогда не будет вызван.НО если ваш create curl снаружи выполняется с это (предположим, что родительский элемент MyThread является основным потоком) в качестве родительского элемента :

MyThread::MyThread(){
  curl = new Curl(this);
  connect( curl, SIGNAL(OnTransfer(QString)), this, SLOTS(OnTransfer(QString)) );
  start();
}
void MyThread::run(){
  curl->Download("http://google.com");
}

Этот будет работать так, как вы ожидали.Будет вызван OnTransfer.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top