python - 如何在不同的线程中生成异常
问题描述
晚安,我正在尝试在此示例代码中生成异常,如果在更改 QLineEdit 中的文本时无法将文本转换为数字,则会生成异常。
但是,当我运行时,出现错误并且程序停止
错误:
QObject::setParent: Cannot set parent, new parent is in a different thread
这是代码:
from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox
from PyQt5 import QtCore
from PyQt5 import uic
import threading
class TheThread(threading.Thread):
def __init__(self,text):
threading.Thread.__init__(self)
self.tx = text
def run(self):
try:
print(int(self.tx),"number")
except:
QMessageBox.critical(None,"Error","Error ",QMessageBox.Ok)
class Principal(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
uic.loadUi("test.ui",self)
self.lineEdit.textChanged.connect(lambda:self.evalNumeros(self.lineEdit.text()))
@QtCore.pyqtSlot(str)
def evalNumeros(self,texto):
print(texto)
try:
threadClass = TheThread(texto)
threadClass.start()
except:
print("error")
app = QApplication([])
p = Principal()
p.show()
app.exec_()
这是此代码 test.ui 的 filu.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>641</width>
<height>479</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLineEdit" name="lineEdit">
<property name="geometry">
<rect>
<x>200</x>
<y>100</y>
<width>191</width>
<height>20</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="yes">
<property name="geometry">
<rect>
<x>170</x>
<y>150</y>
<width>111</width>
<height>31</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">color:white;
background:red;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="no">
<property name="geometry">
<rect>
<x>300</x>
<y>150</y>
<width>111</width>
<height>31</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">color:white;
background:green;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>641</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
解决方案
问题是你不能在另一个线程中直接调用 GUI,所以有两种可能的解决方案:使用信号调用显示 QMessageBox 的方法或使用 QMetaObject.invokeMethod 调用该方法,在这种情况下我将使用第二自第一个以来,SO中有很多例子。
from PyQt5 import QtCore, QtWidgets, uic
from PyQt5 import uic
import threading
class TheThread(threading.Thread):
def __init__(self, text, obj):
threading.Thread.__init__(self)
self.tx = text
self.obj = obj
def run(self):
try:
print(int(self.tx),"number")
except:
QtCore.QMetaObject.invokeMethod(self.obj, "onError",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, "Error"),
QtCore.Q_ARG(str, "Error"))
class Principal(QtWidgets.QMainWindow):
def __init__(self):
super(Principal, self).__init__()
uic.loadUi("test.ui",self)
self.lineEdit.textChanged.connect(self.evalNumeros)
@QtCore.pyqtSlot(str)
def evalNumeros(self,texto):
threadClass = TheThread(texto, self)
threadClass.start()
@QtCore.pyqtSlot(str, str)
def onError(self, title, text):
QtWidgets.QMessageBox.critical(None, title, text, QtWidgets.QMessageBox.Ok)
app = QtWidgets.QApplication([])
p = Principal()
p.show()
app.exec_()
推荐阅读
- java - 休眠公式未设置值
- html - flexbox布局和嵌套滚动条的问题
- git - 获取使用 Git 修改文件最多的用户
- deep-learning - 将jpg文件转换为png是否有任何信息丢失?
- python - 查找图像中所有像素对之间的距离
- python - 将爱尔兰网格(北距和东距)转换为正确的北距和东距
- casting - COGNOS 11 连接字符长度
- google-cloud-data-fusion - Google Cloud Data Fusion 正在将一列附加到原始数据
- python - 如何调整一个类的 __dict__ 以便在使用 type() 时在另一个类中工作?TypeError:描述符不适用
- swift - 用字符替换字符串子范围并在 Swift 中保持长度