PyQt4:无法从另一个线程启动计时器

时间:2011-04-23 16:20:43

标签: python multithreading progress-bar pyqt4

当我运行以下代码时......

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 个答案:

答案 0 :(得分:1)

正如我在评论中提到的,您所看到的错误可以为您提供准确提供的信息。您不能从与创建计时器的线程不同的线程调用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方法,该方法会创建警告。

现在,我不确定你的问题是什么?您是否绝对需要直接从另一个线程控制进度条?这不是一个好主意。