使用线程在异常时创建新的 qwidget
Creating a new qwidget on exception using a thread
from PyQt4 import QtGui
import threading
import sys
class Window(QtGui.QWidget):
def __init__(self):
super().__init__()
self.button = QtGui.QPushButton('click', self)
self.button.clicked.connect(self.mythread)
def mythread(self):
self.t=threading.Thread(target=self.action)
self.t.start()
def action(self):
try:
raise FileExistsError
except FileExistsError:
self.errorwindow = QtGui.QWidget()
self.errorwindow.setGeometry(200, 200, 200, 100)
self.errortext = QtGui.QLabel('error', self.errorwindow)
self.errorwindow.show()
print('1')
def main():
program = QtGui.QApplication(sys.argv)
a=Window()
a.setGeometry(300, 300, 200, 100)
a.show()
sys.exit(program.exec_())
if __name__=='__main__':
main()
在这里很容易看出,我正在尝试制作一种 "oops! an error occured" 类型的 window ,它会在线程出现异常时创建。这是一个示例代码,显示了我是如何尝试这样做的,当您 运行 执行此操作时,您会看到 window 显示一小会儿然后消失。在我的实际程序中,它甚至会导致崩溃。 print('1')
是为了查看解释器是否到达该行,是的,它打印了“1”。所以这并不是说它根本没有 运行 异常块,它确实存在,但它不会创建 qwidget。我做错了什么?
除了创建的线程之外,您永远不应该从任何线程执行 GUI 操作
QApplication
。因此,您的异常处理程序必须在主线程中 运行 并通过信号槽机制调用:
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import pyqtSignal
class MyThread(QtCore.QThread):
somethingIsWrong = pyqtSignal(Exception)
def run(self):
try:
raise FileExistsError
except FileExistsError as e:
self.somethingIsWrong.emit(e)
class Window(QtGui.QWidget):
def __init__(self):
super(QtGui.QWidget, self).__init__()
self.button = QtGui.QPushButton('click', self)
self.button.clicked.connect(self.mythread)
def mythread(self):
self.t = MyThread()
self.t.somethingIsWrong.connect(self.handleException)
self.t.start()
def handleException(self, exception):
self.errorwindow = QtGui.QWidget()
self.errorwindow.setGeometry(200, 200, 200, 100)
self.errortext = QtGui.QLabel('error', self.errorwindow)
self.errorwindow.show()
print(exception.__class__)
from PyQt4 import QtGui
import threading
import sys
class Window(QtGui.QWidget):
def __init__(self):
super().__init__()
self.button = QtGui.QPushButton('click', self)
self.button.clicked.connect(self.mythread)
def mythread(self):
self.t=threading.Thread(target=self.action)
self.t.start()
def action(self):
try:
raise FileExistsError
except FileExistsError:
self.errorwindow = QtGui.QWidget()
self.errorwindow.setGeometry(200, 200, 200, 100)
self.errortext = QtGui.QLabel('error', self.errorwindow)
self.errorwindow.show()
print('1')
def main():
program = QtGui.QApplication(sys.argv)
a=Window()
a.setGeometry(300, 300, 200, 100)
a.show()
sys.exit(program.exec_())
if __name__=='__main__':
main()
在这里很容易看出,我正在尝试制作一种 "oops! an error occured" 类型的 window ,它会在线程出现异常时创建。这是一个示例代码,显示了我是如何尝试这样做的,当您 运行 执行此操作时,您会看到 window 显示一小会儿然后消失。在我的实际程序中,它甚至会导致崩溃。 print('1')
是为了查看解释器是否到达该行,是的,它打印了“1”。所以这并不是说它根本没有 运行 异常块,它确实存在,但它不会创建 qwidget。我做错了什么?
除了创建的线程之外,您永远不应该从任何线程执行 GUI 操作
QApplication
。因此,您的异常处理程序必须在主线程中 运行 并通过信号槽机制调用:
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import pyqtSignal
class MyThread(QtCore.QThread):
somethingIsWrong = pyqtSignal(Exception)
def run(self):
try:
raise FileExistsError
except FileExistsError as e:
self.somethingIsWrong.emit(e)
class Window(QtGui.QWidget):
def __init__(self):
super(QtGui.QWidget, self).__init__()
self.button = QtGui.QPushButton('click', self)
self.button.clicked.connect(self.mythread)
def mythread(self):
self.t = MyThread()
self.t.somethingIsWrong.connect(self.handleException)
self.t.start()
def handleException(self, exception):
self.errorwindow = QtGui.QWidget()
self.errorwindow.setGeometry(200, 200, 200, 100)
self.errortext = QtGui.QLabel('error', self.errorwindow)
self.errorwindow.show()
print(exception.__class__)