QThread, блокирующий главное приложение

У меня есть простая форма UI, который имеет слот для кнопки, запуская поток:

void MainWindow::LoadImage()
{
    aThread->run();
}

И выполнение () метод похоже на это:

void CameraThread::run()
{
    qDebug("Staring Thread");
    while(1)
    {
        qDebug("ping");
        QThread::sleep(1);
    }
}

Когда я нажимаю кнопку, которая называет LoadImage (), UI становится безразличным. Я периодически вижу, что "ping" обменивается сообщениями как вывод отладки, но UI зависает, ни на что не отвечает. Почему мой поток не работает отдельно? CameraThread произошел как общедоступный QThread, я использую gcc версию 4.4.3 (4.4.3-4ubuntu5 Ubuntu) с библиотеками QT и спокойным Создателем из репозиториев Ubuntu 10.04 (x86).

9
задан Atilla Filiz 9 July 2010 в 14:47
поделиться

3 ответа

Краткий ответ: Запустите поток, вызвав aThread-> start (); не run () , и убедитесь, что метод run () вашего потока защищен ( не публично).

Пояснение

Вызов start () - это правильный способ запустить поток, поскольку он обеспечивает планирование приоритетов и фактически выполняет метод run () в своем собственный контекст потока.

Похоже, вы собираетесь загружать изображения в этом потоке, поэтому я собираюсь включить несколько советов, прежде чем вы столкнетесь с ловушками, в которые попадают многие люди при использовании QThread

  1. Сам QThread не является потоком. Это просто оболочка вокруг потока, это подводит нас к ..
  2. сигналы / слоты, определенные в классе CameraThread , не обязательно будут выполняться в контексте потока , помните только о Метод run () и вызываемые из него методы выполняются в отдельном потоке.

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

class ImageLoader : public QObject {
Q_OBJECT
public slots:
    void doWork() 
    {
        // do work
    }
};

void MainWindow::MainWindow(/*params*/) 
{
  ImageLoader loader;
  QThread thread;
  loader.moveToThread( &thread );
  connect( this, SIGNAL( loadImage() ), &loader ,SLOT( doWork() ) );
  thread.start();
  // other initialization
}
void MainWindow::LoadImage()
{
   emit loadImage();
}

Также прочтите блог Qt по этой теме.

30
ответ дан 4 December 2019 в 06:49
поделиться

Я думаю, проблема может заключаться в том, что вы не вызываете QtCore.QThread._init __ (self) в конструкторе. Я была такая же проблема. Также я думаю, вам не следует переопределять функцию запуска, просто переопределите функцию run (). Это решило ту же проблему, что и у меня. Даже без каких-либо задержек sleep () окно должно реагировать.

-1
ответ дан 4 December 2019 в 06:49
поделиться

Вы должны вызвать thread-> start () not run ... run - это точка входа для потока. Поток запускается со старта. Вы вызываете напрямую run, поэтому вы блокируете свой графический интерфейс. Проверьте документацию QThread. virtual void QThread :: run () защищен (не без причины)

5
ответ дан 4 December 2019 в 06:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: