Python 3.x 在线程类的pyqt4中不显示setText()或其他显示方法的任何内容
我用pyqt4和python3.3中的线程编写了一个简单的socket应用程序,但是我在运行Qt类命令时遇到了问题,比如在标签中显示消息或其他任何东西,只有python代码可以正常工作 不向我的gui中的S_标签显示任何内容 我使用两种方式在S_标签上显示任何消息,但两种方式都不起作用Python 3.x 在线程类的pyqt4中不显示setText()或其他显示方法的任何内容,python-3.x,pyqt4,qthread,Python 3.x,Pyqt4,Qthread,我用pyqt4和python3.3中的线程编写了一个简单的socket应用程序,但是我在运行Qt类命令时遇到了问题,比如在标签中显示消息或其他任何东西,只有python代码可以正常工作 不向我的gui中的S_标签显示任何内容 我使用两种方式在S_标签上显示任何消息,但两种方式都不起作用 自我评价 self.ui 代码: self.ui.S_label.setText(“test!”) self.\u ui.S\u label.setText(“测试!”) self.ui.S_label.setT
打印
效果良好:
打印
输出:
-
-
我做错了什么
我的代码:
from PyQt4 import QtCore, QtGui
from imigui import Ui_MainWindow
class imiserv(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.Sport_lineEdit.setMaxLength(5)
self.ui.Sconnect_pushButton.clicked.connect(self.serv)
def serv(self):
self.sersock= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sersock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.host= str(self.ui.Sip_lineEdit.text())
self.port= int(self.ui.Sport_lineEdit.text())
MY_LOCK = threading.Lock()
class CountT(threading.Thread, imiserv):
def __init__(self, ui, ser):
super().__init__()
imiserv.__init__(self)
self._sersock= ser
self._ui= ui
print(self._ui)
print(self.ui)
self.ui.S_label.setText("test !")
self._ui.S_label.setText("test !")
def run(self):
MY_LOCK.acquire()
while True:
cliconn, (addr, remoport)= self._sersock.accept()
self.cstr= cliconn.recv(1024)
self.ui.S_label.setText("{0}:{1} is connected.".format(addr, remoport))
cliconn.close()
print(self.cstr)
MY_LOCK.release()
try :
self.sersock.bind((self.host, self.port))
self.sersock.listen(5)
a= CountT(self.ui, self.sersock)
a.daemon= True # for exit from thread when close gui
a.start()
except socket.error as err:
self.ui.S_label.setText(err)
编辑(新问题):
我对你的方式有一个新的问题:我在gui中添加了一个qtextedit,当我想在代码中设置它时
分段错误发生了,应用程序崩溃了
错误:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTextDocument(0x15c4460), parent's thread is QThread(0xfeb570), current thread is QThread(0x15d3900)
Segmentation fault
我的代码:
from PyQt4 import QtCore, QtGui
from imigui import Ui_MainWindow
class imiserv(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.Sport_lineEdit.setMaxLength(5)
self.ui.Sconnect_pushButton.clicked.connect(self.serv)
def serv(self):
self.sersock= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sersock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.host= str(self.ui.Sip_lineEdit.text())
self.port= int(self.ui.Sport_lineEdit.text())
MY_LOCK = threading.Lock()
class CountT(threading.Thread):
def __init__(self, label, ser, qtext):
super().__init__()
self._sersock= ser
self._uilabel= label
self._uiClog= qtext
def run(self):
MY_LOCK.acquire()
while True:
cliconn, (addr, remoport)= self._sersock.accept()
self.cstr= cliconn.recv(1024)
self._uilabel.setText("{0}:{1} is connected.".format(addr, remoport))
cliconn.close()
print(self.cstr)
self._uilabel.setText(self.cstr) # it's ok!
self._uiClog.setText(msg) # Segmentation fault
MY_LOCK.release()
try :
self.sersock.bind((self.host, self.port))
self.sersock.listen(5)
a= CountT(label= self.ui.S_label, ser= self.sersock, qtext= self.ui.Clog_textEdit)
a.daemon= True # for exit from thread when close gui
a.start()
self.ui.S_label.setText("Connected !")
except socket.error as err:
self.ui.S_label.setText(err) # it's ok !
self.ui.self.ui.Clog_textEdit.setText(err) # it's ok !
为什么?
编辑(新问题2):
这是我的代码:
从PyQt4导入QtCore、QtGui
从imigui导入Ui_主窗口
类imiserv(QtGui.QMainWindow):
这是交叉发生的错误,我应该为get事件按两次按钮,在linux中第一次显示错误,在windows中没有显示,第二次按事件发生(此错误仅在linux操作系统中显示)
下面的代码适合我(这里是Python 2.6)。我用imiserv
删除了CountT
的继承,并用QLabelS_标签
替换了ui对象,取而代之的是imiserv
实例。pyqtsignal
允许线程计数将文本写入QLabel和QTextEdit:
import socket
import threading
from PyQt4 import QtCore, QtGui
from imigui import Ui_MainWindow
class imiserv(QtGui.QMainWindow):
send_msg = pyqtSignal('QString', 'QString')
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.Sport_lineEdit.setMaxLength(5)
self.ui.Sconnect_pushButton.clicked.connect(self.serv)
self.send_msg.connect(self.my_slot)
def write_msg(self, lbl_msg, txt_msg):
self.ui.S_label.setText(lbl_msg)
self.ui.Clog_textEdit.setText(txt_msg)
def serv(self):
self.sersock= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sersock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.host= str(self.ui.Sip_lineEdit.text())
self.port= int(self.ui.Sport_lineEdit.text())
MY_LOCK = threading.Lock()
class CountT(threading.Thread):
def __init__(self, parent):
threading.Thread.__init__(self)
self._parent= parent
def run(self):
MY_LOCK.acquire()
self._parent.send_msg.emit("Waiting connections","")
while True:
cliconn, (addr, remoport)= self.__parent.sersock.accept()
self.cstr= cliconn.recv(1024)
self._parent.send_msg.emit("{0}:{1} is connected.".format(addr, remoport), self.cstr)
cliconn.close()
MY_LOCK.release()
try :
self.sersock.bind((self.host, self.port))
self.sersock.listen(5)
a= CountT(self)
a.daemon= True # for exit from thread when close gui
a.start()
except socket.error as err:
self.ui.S_label.setText(err.strerror.decode("utf-8"))
self.ui.Clog_textEdit.setText(err.strerror.decode("utf-8"))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
s = imiserv()
s.show()
sys.exit(app.exec_())
完全有效!!!谢谢,但是你能告诉我为什么会发生这个问题吗??为什么继承不起作用?这样做有什么错?继承毫无意义,但我认为这不是问题所在。将lineedit小部件作为参数解决了问题。您的方式有一个新问题:我在gui中添加了一个qtextedit,当我想在代码中设置它时,出现了“分段错误”:QObject:无法为处于不同线程中的父级创建子级。(父线程是QTextDocument(0x15c4460),父线程是QThread(0xfeb570),当前线程是QThread(0x15d3900)分段错误,为什么?将文本写入QTextEdit会导致异常,因为它是在另一个线程中完成的。我不知道为什么这不是QLabel的问题。我编辑了我的答案:向imserv类添加了一个信号。该信号连接到设计用于在QLabel和QTextEdit中写入文本的插槽。该信号为emit注意,CounT类现在只有一个构造函数参数:imiserv实例。CounT实例现在可以访问套接字和pyqtsignal。是的,您可以使用self.\u parent
访问imiserv实例的所有成员。这只是标准Python:您给一个类一个insta它允许您使用它的方法并访问它的属性。在您的情况下,这允许避免直接从线程中进行任何与Qt相关的调用。
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.3/threading.py", line 637, in _bootstrap_inner
self.run()
File "imiclilap.py", line 34, in run
cliconn, (addr, remoport)= self._parent.clis.accept()
File "/usr/lib/python3.3/socket.py", line 135, in accept
fd, addr = self._accept()
OSError: [Errno 22] Invalid argument
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python3.3/threading.py", line 637, in _bootstrap_inner
self.run()
File "imiclilap.py", line 34, in run
cliconn, (addr, remoport)= self._parent.clis.accept()
File "/usr/lib/python3.3/socket.py", line 135, in accept
fd, addr = self._accept()
OSError: [Errno 22] Invalid argument
import socket
import threading
from PyQt4 import QtCore, QtGui
from imigui import Ui_MainWindow
class imiserv(QtGui.QMainWindow):
send_msg = pyqtSignal('QString', 'QString')
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.Sport_lineEdit.setMaxLength(5)
self.ui.Sconnect_pushButton.clicked.connect(self.serv)
self.send_msg.connect(self.my_slot)
def write_msg(self, lbl_msg, txt_msg):
self.ui.S_label.setText(lbl_msg)
self.ui.Clog_textEdit.setText(txt_msg)
def serv(self):
self.sersock= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sersock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.host= str(self.ui.Sip_lineEdit.text())
self.port= int(self.ui.Sport_lineEdit.text())
MY_LOCK = threading.Lock()
class CountT(threading.Thread):
def __init__(self, parent):
threading.Thread.__init__(self)
self._parent= parent
def run(self):
MY_LOCK.acquire()
self._parent.send_msg.emit("Waiting connections","")
while True:
cliconn, (addr, remoport)= self.__parent.sersock.accept()
self.cstr= cliconn.recv(1024)
self._parent.send_msg.emit("{0}:{1} is connected.".format(addr, remoport), self.cstr)
cliconn.close()
MY_LOCK.release()
try :
self.sersock.bind((self.host, self.port))
self.sersock.listen(5)
a= CountT(self)
a.daemon= True # for exit from thread when close gui
a.start()
except socket.error as err:
self.ui.S_label.setText(err.strerror.decode("utf-8"))
self.ui.Clog_textEdit.setText(err.strerror.decode("utf-8"))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
s = imiserv()
s.show()
sys.exit(app.exec_())