2013-11-07 4 views
0

Я только недавно начал работать с API QThreads и столкнулся с нечетной проблемой.QThread блокирует цикл событий

Я создал подкласс QThread с Переопределённой Run() методом Здесь:

void ThreadChecker::run() 
{ 
    emit TotalDbSize(1000); 

    for (int i = 0; i < 1000; i++) 
    { 
     QString number; 
     number.setNum(i); 
     number.append("\n"); 
     emit SimpleMessage(number); 
     //pausing is necessary, since in the real program the thread will perform quite lenghty tasks 
     usleep(10000); 
    } 
} 

Вот код, который вызывает эту тему:

ThreadChecker thread; 


connect(&thread, SIGNAL(TotalDbSize(int)), this, SLOT(SetMaximumProgress(int))); 
//This slot writes the message into the QTextEdit 
connect(&thread, SIGNAL(SimpleMessage(QString)), this, SLOT(ProcessSimpleMessage(QString))); 

thread.start(); 

Как я намереваюсь это работать для обновления QTextEdit каждые 10 миллисекунд. Но вместо этого программа просто отстает на 10 секунд, а затем все сигналы сразу бросаются. Moreso, в то время как программа отстает, она ведет себя так же, как цикл события заблокирован (кнопки не будут [ress, изменение размера не работает и т. Д.)

Что мне здесь не хватает?

+0

попытайтесь добавить в свой 'ThreadChecker' ctor:' moveToThread (this) '. Обратите внимание, что это ** НЕ ** решение. Это просто проверить, помогает ли это, чтобы лучше понять вашу проблему. – ixSci

+0

Если по ctor вы имеете в виду конструктор, то это не исправить вопрос – WereWind

+0

Почему бы вам просто не использовать QTimer? – vahancho

ответ

1

Попробуйте следующий код:

class Updater: public QObject 
{ 
    Q_OBJECT 
public slots: 
    void updateLoop() 
    { 
     emit TotalDbSize(1000); 

     for (int i = 0; i < 1000; i++) 
     { 
      QString number; 
      number.setNum(i); 
      number.append("\n"); 
      emit SimpleMessage(number); 
      //pausing is necessary, since in the real program the thread will perform quite lenghty tasks 
      usleep(10000); 
     } 
    } 
signals: 
    void TotalDbSize(...); 
    void SimpleMessage(...); 

}; 
... 
QThread updaterThread; 
Updater updater; 
updater.moveToThread(&updaterThread); 
connect(&updater, SIGNAL(TotalDbSize(int)), this, SLOT(SetMaximumProgress(int))); 
//This slot writes the message into the QTextEdit 
connect(&updater, SIGNAL(SimpleMessage(QString)), this, SLOT(ProcessSimpleMessage(QString))); 
connect(&updaterThread, SIGNAL(started()), &updater, SLOT(updateLoop())); 
updaterThread.start(); 

Я не проверял, хотя. Обратите внимание, что вы должны гарантировать, что updaterThread и updater не выйдут из сферы действия.

======

Почему код из вопроса не работает? Я могу только догадываться: у вас есть ваши сигналы, прикрепленные к объекту QThread, и когда вы делаете connect, у вас есть прямое соединение, так как thread и this находятся в одном потоке. Поэтому, когда вы испускаете сигнал, прямое соединение работает, и вы обновляете свой TextBox за пределами потока графического интерфейса, который является неправильным и может привести к каким-либо результатам. Обратите внимание, однако, что моя догадка может быть неправильной, и точную причину можно найти с помощью отладчика.

Также прочитайте статью Threads, Events and QObjects. Это отличная статья, чтобы понять, как правильно использовать потоки в Qt.

+0

Я пробовал это, и он работает как шарм. Благодарю. Теперь я просто curiuos, почему мой оригинальный код не работал так, как предполагалось? из того, что я собрал, подклассификация QThread устарела и соответствует принципам ООП, но не ошибается – WereWind

+0

@WereWind, если вы не хотите изменять управление потоками, подклассификация QThread неверна; http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/ – TheDarkKnight

+0

Вы также найдете это полезным: http://mayaposch.wordpress.com/2011/11/01/how-to-really-really-use-qthreads-the-full-explain/ – TheDarkKnight

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