晚安,我试图在此示例代码中生成一个异常,如果在更改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_()
这是此代码的filu.ui test.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>
答案 0 :(得分:1)
问题是您不能在另一个线程中直接调用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_()