2012-03-09 2 views
1

У меня есть случай, когда сигнал теряется, и я не понимаю, почему - обычно сигналы, отправленные до цикла событий, запускаются, просто выстраиваются в очередь и отправляются тогда.Сигнал перед началом цикла цикла QThread потерян

Это то, что код выглядит следующим образом (для объекта QThread):

void OffloadHandler::run() 
{ 
    cout << "Start" << endl; 
    connect(this, SIGNAL(loopStarted()), SLOT(onLoopStarted()), Qt::QueuedConnection); 
    emit loopStarted(); 
    exec(); 
} 

void OffloadHandler::onLoopStarted() 
{ 
    cout << "Here!" << endl; 
} 

Нить начинается в другом месте и Start записывается в консоли, но Here1 никогда не - сигнал не принимается. Я использую один и тот же шаблон в своем основном цикле сообщений, и он работает, но в этом поточном контуре сообщений он не работает.

В коде есть что-то явно неправильное?

+0

Где находится этот «loopStarted»? – Koying

+0

Прямо там в нитке. –

ответ

0

Хорошо, я понял, я был укушен странностью QThread. Нужно быть очень осторожным при подключении к самому объекту QThread, поскольку этот объект по умолчанию не принадлежит потоку.

Таким образом, в точке, где поток создается я должен переместить нить к нити:

OffloadHandler * oh = new OffloadHandler(); 
oh->moveToThread(oh); //MOVE TO SELF! 
oh->start(); 

После того, как я это делаю сигналы работают, как и ожидалось.

+0

Хотя документация Qt рекомендует подклассифицировать QThread, это обычно считается противоречащим предполагаемому использованию. Перемещение потока в себя, безусловно, является распространенным анти-шаблоном, который продолжает распространяться :) Он может решить вашу непосредственную проблему, но проблемы, которые он создает, более коварны. Сделайте поиск по SO для Qt и потоков, и вы должны найти много упоминаний об этой статье: http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/ –

+0

Хотя, возможно, приятно идея не подкласса. Я не вижу, чтобы вы могли запустить цикл сообщений в потоке. 'exec' - это защищенная функция-член, и для этой цели кажется довольно глупым создание нового QEventLoop. –

+0

Я также не покупаю бит о том, чтобы не переместить нить в себя. В потоке нет потока владельца, что особенно важно в потоке, который произошел для его создания - теперь это самостоятельная независимая сущность. –

1

Ваш код действителен и должен работать. Вы уверены, что в потоке запущен цикл событий, который создан oh?

Причина: emit loopStarted() должен отправить событие в цикл событий oh, который будет обработан и будет звонить по номеру onLoopStarted(). Я проверил ваш код, и он работает для меня.


Btw, Это обычно рекомендуется не добавлять слоты для вашей QThread, и избегать использования moveToThread(this);

К сожалению, я не очень понимаю ваш случай использования, поэтому я не могу дать лучшее решение. Но here - это потрясающая документация, в которой есть хорошие ДО и ДОНТЫ относительно QThread.

+0

+0.5 :) Это интересная статья, но я бы хотел, чтобы она не приводила примеры suclassing 'QThread'. Я считаю, что предложения там, которые сосредоточены на работе в подклассе 'QObject' и переходе на экземпляр' QThread', - лучший выбор. –

Смежные вопросы