PyQt4:定时器不能从另一个线程启动

0 投票
1 回答
4103 浏览
提问于 2025-04-16 16:18

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

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

正如我在评论中提到的,你看到的错误信息其实正是它应该提供给你的信息。你不能在创建定时器的线程之外去调用 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 方法,从而产生警告。

现在,我不太明白你对此有什么问题?你真的需要从另一个线程直接控制进度条吗?这其实不是个好主意。

撰写回答