PyQt4: таймеры не могут быть запущены из другого потока - PullRequest
0 голосов
/ 23 апреля 2011

Когда я запускаю следующий код ...

import sys, time
from PyQt4 import QtCore, QtGui

class WorkThread(QtCore.QThread):
 def __init__(self):
  QtCore.QThread.__init__(self)

 def run(self):
  for i in range(100):
   time.sleep(1) # artificial time delay
   print(i)
   test.pbar.setValue(i)
  return


class MyApp(QtGui.QWidget):
 def __init__(self):
  QtGui.QWidget.__init__(self, None)
  self.setGeometry(300, 300, 280, 600)
  self.setWindowTitle('threads')
  self.layout = QtGui.QVBoxLayout(self)
  self.pbar = QtGui.QProgressBar(self)
  self.layout.addWidget(self.pbar)



# run
app = QtGui.QApplication(sys.argv)
test = MyApp()
workThread = WorkThread()
workThread.start()
test.show()
app.exec_()

Я получаю следующую ошибку ...

QObject::startTimer: timers cannot be started from another thread

Код по-прежнему продолжает выполняться нормально, но я не понимаю, , почему эта ошибка перестает появляться после удаления test.pbar.setValue(i) ИЛИ замените pbar другим виджетом, таким как список. Кажется очевидным, что ошибка относится к виджету индикатора выполнения ...

1 Ответ

1 голос
/ 23 апреля 2011

Как я уже упоминал в своем комментарии, ошибка, которую вы видите, предоставляет вам именно ту информацию, которую она должна была предоставить. Вы не можете вызывать QObject::setTimer из потока, отличного от того, в котором был создан таймер. В частности, одна версия кода QObject, которую я нашел, имеет этот код:

int QObject::startTimer(int interval)
{
    Q_D(QObject);

    if (interval < 0) {
        qWarning("QObject::startTimer: QTimer cannot have a negative interval");
        return 0;
    }

    d->pendTimer = true;                                // set timer flag

    if (!d->threadData->eventDispatcher) {
        qWarning("QObject::startTimer: QTimer can only be used with threads started with QThread");
        return 0;
    }
    return d->threadData->eventDispatcher->registerTimer(interval, this);
}

Запишите код, генерирующий предупреждение.

Вызов метода pbar.setValue, очевидно, вызывает этот метод startTimer, который создает предупреждение.

Теперь я не уверен, в чем ваша проблема с этим? Вам абсолютно необходимо контролировать индикатор выполнения прямо из другого потока? Это не очень хорошая идея.

...