由于计时器错误,PyQt 一直关闭很可能

PyQt keeps closing most likely due to timer error

我正在尝试让一行文本显示在 pyqt4 文本浏览器中。我能够让它显示,但每当我开始调整 window 的大小时,我 运行 函数 PyQt window 关闭。目前,它只是关闭而没有显示错误或其他任何内容。在它显示此错误之前:

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

我已经尝试了 .append() 和 .instertPlainText()。附加是我从中得到错误的地方。感谢您的帮助,如有不明之处请见谅。

这是我的代码:

class MyForm(QtGui.QMainWindow):                                                                               
   def __init__(self, parent=None):                                                                         
      QtGui.QWidget.__init__(self, parent)                                                                           
      self.ui = Ui_MainWindow()                                                                          
      self.ui.setupUi(self)
      self.stopAutoRun=0
      self.ui.autoButton.clicked.connect(self.autoRun)
      self.waitTime=.2
   '''
   ________________________________________________________________________________
                                          autoRun
   Description: will continously look for a new JSON file and process it once it appears
  _______________________________________________________
  '''
  def autoRun(self):
     self.task1=threading.Thread(target=self.autoRunThread)                                                                                                        
     self.task1.setDaemon(True)                                                                                                                      
     self.task1.start()

  def autoRunThread(self):
     self.task1=threading.currentThread()
     while getattr(self.task1,"run",True):
        commands=powerSupply.setValuesFile()
        data=powerSupply.readValues()
        self.ui.commandOutput.insertPlainText(str(data))
        time.sleep(self.waitTime)

ui:

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(1270, 805)
        MainWindow.setMinimumSize(QtCore.QSize(0, 0))
        MainWindow.setMouseTracking(True)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.verticalLayout_3 = QtGui.QVBoxLayout(self.centralwidget)
        self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
        self.verticalLayout_3.addItem(spacerItem)
        self.gridLayout_3 = QtGui.QGridLayout()
        self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3"))
        self.verticalLayout = QtGui.QVBoxLayout()
        self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
        spacerItem1 = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
        self.verticalLayout.addItem(spacerItem1)
        self.openButton = QtGui.QPushButton(self.centralwidget)
        self.openButton.setMinimumSize(QtCore.QSize(140, 28))
        self.openButton.setMaximumSize(QtCore.QSize(140, 28))
        self.openButton.setObjectName(_fromUtf8("openButton"))
        self.verticalLayout.addWidget(self.openButton)
        spacerItem2 = QtGui.QSpacerItem(20, 10, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
        self.verticalLayout.addItem(spacerItem2)
        self.runButton = QtGui.QPushButton(self.centralwidget)
        self.runButton.setMinimumSize(QtCore.QSize(140, 28))
        self.runButton.setMaximumSize(QtCore.QSize(140, 28))
        self.runButton.setObjectName(_fromUtf8("runButton"))
        self.verticalLayout.addWidget(self.runButton)
        spacerItem3 = QtGui.QSpacerItem(20, 10, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
        self.verticalLayout.addItem(spacerItem3)
        self.autoButton = QtGui.QPushButton(self.centralwidget)
        self.autoButton.setObjectName(_fromUtf8("autoButton"))
        self.verticalLayout.addWidget(self.autoButton)
        spacerItem4 = QtGui.QSpacerItem(20, 10, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
        self.verticalLayout.addItem(spacerItem4)
        self.stopAutoButton = QtGui.QPushButton(self.centralwidget)
        self.stopAutoButton.setObjectName(_fromUtf8("stopAutoButton"))
        self.verticalLayout.addWidget(self.stopAutoButton)
        spacerItem5 = QtGui.QSpacerItem(20, 10, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
        self.verticalLayout.addItem(spacerItem5)
        self.outputButton = QtGui.QPushButton(self.centralwidget)
        self.outputButton.setMinimumSize(QtCore.QSize(140, 28))
        self.outputButton.setMaximumSize(QtCore.QSize(140, 28))
        self.outputButton.setStyleSheet(_fromUtf8("\n"
""))
        self.outputButton.setObjectName(_fromUtf8("outputButton"))
        self.verticalLayout.addWidget(self.outputButton)
        spacerItem6 = QtGui.QSpacerItem(20, 10, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
        self.verticalLayout.addItem(spacerItem6)
        self.powerOffButton = QtGui.QPushButton(self.centralwidget)
        self.powerOffButton.setStyleSheet(_fromUtf8("background-color: rgb(255, 0, 0);"))
        self.powerOffButton.setObjectName(_fromUtf8("powerOffButton"))
        self.verticalLayout.addWidget(self.powerOffButton)
        spacerItem7 = QtGui.QSpacerItem(20, 10, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
        self.verticalLayout.addItem(spacerItem7)
        self.powerButton = QtGui.QPushButton(self.centralwidget)
        self.powerButton.setMinimumSize(QtCore.QSize(140, 28))
        self.powerButton.setMaximumSize(QtCore.QSize(100, 28))
        self.powerButton.setMouseTracking(True)
        self.powerButton.setAcceptDrops(False)
        self.powerButton.setStatusTip(_fromUtf8(""))
        self.powerButton.setStyleSheet(_fromUtf8("background-color: rgb(255, 0, 0);"))
        self.powerButton.setObjectName(_fromUtf8("powerButton"))
        self.verticalLayout.addWidget(self.powerButton)
        spacerItem8 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem8)
        self.gridLayout_3.addLayout(self.verticalLayout, 0, 0, 1, 1)
        self.horizontalLayout_2 = QtGui.QHBoxLayout()
        self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
        self.verticalLayout_2 = QtGui.QVBoxLayout()
        self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
        self.label = QtGui.QLabel(self.centralwidget)
        self.label.setObjectName(_fromUtf8("label"))
        self.verticalLayout_2.addWidget(self.label)
        self.commandInput = QtGui.QTextBrowser(self.centralwidget)
        self.commandInput.setMinimumSize(QtCore.QSize(600, 300))
        self.commandInput.setObjectName(_fromUtf8("commandInput"))
        self.verticalLayout_2.addWidget(self.commandInput)
        self.horizontalLayout_2.addLayout(self.verticalLayout_2)
        self.gridLayout_3.addLayout(self.horizontalLayout_2, 0, 1, 1, 1)
        self.verticalLayout_3.addLayout(self.gridLayout_3)
        self.label_2 = QtGui.QLabel(self.centralwidget)
        self.label_2.setObjectName(_fromUtf8("label_2"))
        self.verticalLayout_3.addWidget(self.label_2)
        self.commandOutput = QtGui.QTextBrowser(self.centralwidget)
        self.commandOutput.setMaximumSize(QtCore.QSize(16777215, 100))
        self.commandOutput.setObjectName(_fromUtf8("commandOutput"))
        self.verticalLayout_3.addWidget(self.commandOutput)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1270, 26))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.openButton.setToolTip(_translate("MainWindow", "manually chose a JSON file to run", None))
        self.openButton.setText(_translate("MainWindow", "Open File", None))
        self.runButton.setToolTip(_translate("MainWindow", "runs the chosen JSON file", None))
        self.runButton.setText(_translate("MainWindow", "Run File", None))
        self.autoButton.setToolTip(_translate("MainWindow", "starts to automatically run new JSON files in directory", None))
        self.autoButton.setText(_translate("MainWindow", "Auto Run", None))
        self.stopAutoButton.setToolTip(_translate("MainWindow", "Stops the auto run funtion", None))
        self.stopAutoButton.setText(_translate("MainWindow", "Stop Auto Run", None))
        self.outputButton.setToolTip(_translate("MainWindow", "changes where the file is being stored during while this GUI instance is open", None))
        self.outputButton.setText(_translate("MainWindow", "Change Output File", None))
        self.powerOffButton.setToolTip(_translate("MainWindow", "Turns off Voltage output", None))
        self.powerOffButton.setText(_translate("MainWindow", "Voltage Off", None))
        self.powerButton.setToolTip(_translate("MainWindow", "Closes Voltage Output and shuts down GUI", None))
        self.powerButton.setText(_translate("MainWindow", "Voltage Off and Exit", None))
        self.label.setText(_translate("MainWindow", "Command Input", None))
        self.label_2.setText(_translate("MainWindow", "Command Output", None))

主线程是唯一应该更新 GUI 的线程,如果你想从另一个线程更新视图的任何部分,你必须使用信号,在你的情况下:

class MyForm(QtGui.QMainWindow):  
    signal = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):                                                                         
        QtGui.QMainWindow.__init__(self, parent) 
        self.ui = Ui_MainWindow()                                                                          
        self.ui.setupUi(self)
        self.signal.connect(self.ui.commandOutput.insertPlainText)
        [...]

    def autoRun(self):
        [...]

    def autoRunThread(self):
        self.task1=threading.currentThread()
        while getattr(self.task1,"run",True):
            commands=powerSupply.setValuesFile()
            data=powerSupply.readValues()
            self.signal.emit(str(data))
            time.sleep(self.waitTime)