Qt посылает сигнал объекту, перемещенному в поток

Чтобы инициировать остановку потока, установив флаг (и затем вернувшись из потока), мне нужно с ним связаться.

Потоки реализованы так

MyClass* obj = new MyClass(0);
connect( this,SIGNAL( stop() ),obj, SLOT(stop()));
emit stop();    // slot is called (qDebug output)

MyThread = new QThread;
obj->moveToThread(MyThread);
connect( ... started() ... quit() ... finished() ... deleteLater() ...
....

emit stop();    // slot isn't called (qDebug output)

Слот пока не имеет никакой логики, он просто использует вывод qDebug(). Создание объекта и связи происходят в методе главного окна.

К сожалению, я не могу понять, что я делаю неправильно: как только объект перемещен в поток, слот больше не запускается.

2 ответа

Может быть, вы просто забыли скопировать / вставить его, но вам не хватает MyThread->start() вызов. Кроме того, строка, объявляющая поток, должна быть QThread * MyThread = new QThread();, но это была, вероятно, просто опечатка.

Теперь, в своем ответе, вы говорите, что с помощью Qt::DirectConnection кажется, исправил вашу проблему. Однако слот, вызванный с использованием прямого соединения, просто вызывает метод слота напрямую. Метод слота работает, но он запускается из вызывающего потока (где ваш stop() сигнал испускается). Это будет работать, даже если ваш поток не запущен. Что вы действительно хотите, чтобы слот был вызван через Qt::QueuedConnection, Это поместит событие в цикл событий рабочего потока, который затем вызовет слот. Обратите внимание, что Qt будет обрабатывать тип соединения, если вы не укажете.

Если соединение в очереди не работает, то вы, вероятно, блокируете цикл обработки событий своей работой. В своем рабочем методе вы когда-нибудь передаете управление обратно в цикл обработки событий, чтобы позволить ему обрабатывать события? Или это просто работает в while цикл ожидания флага для изменения состояния?

Кроме того, ваш код не компилируется / запускается как есть. Я полагаю, вы справляетесь с QApplication вещи уже - а именно, звонят QApplication::exec() после того, как все настроено в вас main функция. Если ты не позвонишь exec(), главный цикл событий никогда не запускается.

Вывод отладки фактически имел место, только после того, как поток закончил свою работу. С помощью

connect( this, SIGNAL(stop()), obj, SLOT(stop()), Qt::DirectConnection);

решил проблему.

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