在 GUI Close 上终止所有 QThreads
Terminate All QThreads on GUI Close
我有一个 PyQT gui,它有一个 gui 线程,还有 24 个 "tester threads." 它们工作正常,但当我关闭 gui 时似乎仍然无法正常工作。如何优雅地关闭线程以避免 python 崩溃?
#!/usr/bin/python
# Standard Lib
from datetime import datetime
import logging
import os
import random
import sys
import time
# Third Party
from PyQt4 import QtGui, QtCore
# Local Kung Fu
stuff
class SSITesterThread(QtCore.QThread):
# vars for updating gui using signals
updateText = QtCore.pyqtSignal(str)
updateColor = QtCore.pyqtSignal(str)
updateSN = QtCore.pyqtSignal(str)
def __init__(self, thread_number, port, path, parent=None):
super(SSITesterThread, self).__init__(parent)
self.delay = random.random()
def run(self):
self.ssitester()
def ssitester(self):
# stuff
class SSITestSuiteGUI(QtGui.QMainWindow):
def __init__(self, parent=None):
self._threads = []
QtGui.QWidget.__init__(self, parent)
# Init class from template and paths
self.launch_tester_threads()
def init_gui_nodes(self, com_ports_list):
for num, port, in zip(range(1, 25), range(0, 24)):
label = getattr(self.ui, 'com_{}'.format(num))
label.setText("COM Port: {}".format(com_ports_list[port]["COM"]))
def launch_tester_threads(self):
logging.info("Spinning up threads...")
for num, com_port_chunk in zip(range(1, 25), self.com_ports_list):
tester_thread = SSITesterThread(thread_number=num, port=com_port_chunk["COM"], path=self.vc_test_path)
# get a reference to the associated textbox somehow...
status_box = getattr(self.ui, 'status_{}'.format(num))
tester_thread.updateText.connect(status_box.setText)
status_box = getattr(self.ui, 'status_{}'.format(num))
tester_thread.updateColor.connect(status_box.setStyleSheet)
sn_label = getattr(self.ui, 'sn_{}'.format(num))
tester_thread.updateSN.connect(sn_label.setText)
sn_label.setText("S/N: None")
tester_thread.start()
self._threads.append(tester_thread)
logging.info("Ready for tests.")
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
test_suite = SSITestSuiteGUI()
test_suite.show()
# Close app only when window is closed.
sys.exit(app.exec_())
但是出现错误:
attributeerror: 'function' object has no attribute '__pyqtSignature__'
感谢您的宝贵时间。
更新:
将以下建议添加为:
@QtCore.pyqtSlot()
def stop(self):
return
在我的 SSITesterThread Class 中,当各种 "emits" 我在线程中用作信号时突然尝试访问 NoneType 对象时出错:
File in gui.py, line 75 in tester,
self.updateColor.emit("{}".format(thread_colors.green_alert)
AttributeError: "NoneType" object has no attribute 'green alert'
修复成功了吗,这是一个新问题?因为似乎事情仍然没有正常关闭。
您可能只需要将 stop
方法装饰为插槽即可。
@QtCore.pyqtSlot()
def stop(self):
# do thread cleanup, stop thread
您似乎是从 QTDesigner 生成的表单中导入 GUI。试试这个:
self.ui.closeEvent = self.closeEvent
我认为您的问题是您在错误的位置编辑了错误的 QMainWindow 实例。
我有一个 PyQT gui,它有一个 gui 线程,还有 24 个 "tester threads." 它们工作正常,但当我关闭 gui 时似乎仍然无法正常工作。如何优雅地关闭线程以避免 python 崩溃?
#!/usr/bin/python
# Standard Lib
from datetime import datetime
import logging
import os
import random
import sys
import time
# Third Party
from PyQt4 import QtGui, QtCore
# Local Kung Fu
stuff
class SSITesterThread(QtCore.QThread):
# vars for updating gui using signals
updateText = QtCore.pyqtSignal(str)
updateColor = QtCore.pyqtSignal(str)
updateSN = QtCore.pyqtSignal(str)
def __init__(self, thread_number, port, path, parent=None):
super(SSITesterThread, self).__init__(parent)
self.delay = random.random()
def run(self):
self.ssitester()
def ssitester(self):
# stuff
class SSITestSuiteGUI(QtGui.QMainWindow):
def __init__(self, parent=None):
self._threads = []
QtGui.QWidget.__init__(self, parent)
# Init class from template and paths
self.launch_tester_threads()
def init_gui_nodes(self, com_ports_list):
for num, port, in zip(range(1, 25), range(0, 24)):
label = getattr(self.ui, 'com_{}'.format(num))
label.setText("COM Port: {}".format(com_ports_list[port]["COM"]))
def launch_tester_threads(self):
logging.info("Spinning up threads...")
for num, com_port_chunk in zip(range(1, 25), self.com_ports_list):
tester_thread = SSITesterThread(thread_number=num, port=com_port_chunk["COM"], path=self.vc_test_path)
# get a reference to the associated textbox somehow...
status_box = getattr(self.ui, 'status_{}'.format(num))
tester_thread.updateText.connect(status_box.setText)
status_box = getattr(self.ui, 'status_{}'.format(num))
tester_thread.updateColor.connect(status_box.setStyleSheet)
sn_label = getattr(self.ui, 'sn_{}'.format(num))
tester_thread.updateSN.connect(sn_label.setText)
sn_label.setText("S/N: None")
tester_thread.start()
self._threads.append(tester_thread)
logging.info("Ready for tests.")
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
test_suite = SSITestSuiteGUI()
test_suite.show()
# Close app only when window is closed.
sys.exit(app.exec_())
但是出现错误:
attributeerror: 'function' object has no attribute '__pyqtSignature__'
感谢您的宝贵时间。
更新:
将以下建议添加为:
@QtCore.pyqtSlot()
def stop(self):
return
在我的 SSITesterThread Class 中,当各种 "emits" 我在线程中用作信号时突然尝试访问 NoneType 对象时出错:
File in gui.py, line 75 in tester,
self.updateColor.emit("{}".format(thread_colors.green_alert)
AttributeError: "NoneType" object has no attribute 'green alert'
修复成功了吗,这是一个新问题?因为似乎事情仍然没有正常关闭。
您可能只需要将 stop
方法装饰为插槽即可。
@QtCore.pyqtSlot()
def stop(self):
# do thread cleanup, stop thread
您似乎是从 QTDesigner 生成的表单中导入 GUI。试试这个:
self.ui.closeEvent = self.closeEvent
我认为您的问题是您在错误的位置编辑了错误的 QMainWindow 实例。