QThread:使用 GUI 进行线程处理 python
QThread: Threading with GUI python
我正在制作迷你聊天应用程序以提高我在 Python 中的套接字和 GUI 技能。但是每次我启动应用程序时,我的 QThread 都在倾倒。
我需要 运行 带 GUI 的线程
这是client.py
import socket
import sys
from colorama import Fore, Back, Style
from os import system, name
import sys
from chat import Ui_Form as Ui_Form
from login import Ui_Form as Ui_Form1
from PyQt5 import QtCore, QtGui, QtWidgets
from threading import Thread
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
app = QtWidgets.QApplication(sys.argv)
Form_login = QtWidgets.QWidget()
ui_login = Ui_Form1()
ui_login.setupUi(Form_login)
Form_login.show()
Form_chat = QtWidgets.QWidget()
ui_chat = Ui_Form()
ui_chat.setupUi(Form_chat)
history = ''
class listen_thread(QtCore.QObject):
running = False
listen_var = QtCore.pyqtSignal(str)
def run():
print('checkpoint')
while True:
listen_var.emit('message')
QtCore.QThread.msleep(1000)
def connect_pressed():
username = ui_login.lineEdit.text()
Form_login.hide()
Form_chat.show()
sock.connect(('127.0.0.1', 10000))
thread = QtCore.QThread()
listen1 = listen_thread()
listen1.moveToThread(thread)
listen1.listen_var.connect(update_chat_history)
thread.started.connect(listen1.run)
thread.start()
@QtCore.pyqtSlot(str)
def update_chat_history(message):
print(message)
ui_chat.textEdit_2.append(message)
def send_pressed():
message = ui_login.lineEdit.text() + ' > ' + ui_chat.lineEdit.text()
sock.send(bytes(str(message),'utf-8'))
# update_chat_history(message)
ui_chat.lineEdit.setText('')
def listen(some):
while True:
try:
data = sock.recv(1024)
except:
pass
else:
update_chat_history(str(data))
ui_login.pushButton.clicked.connect(connect_pressed)
ui_chat.pushButton.clicked.connect(send_pressed)
sys.exit(app.exec_())
当我启动它时,输出是:
QThread: Destroyed while thread is still running
Aborted (core dumped)
有人可以帮忙吗???
你的问题的解释很简单:在 connect_pressed
中创建的线程在该函数之外没有引用,因此一旦函数 returns.
“简单”的解决方案是在该函数之外创建线程,并且 运行 仅在该处创建线程,或者将线程添加到容器(例如,列表)中:
threads = []
def connect_pressed():
# ...
threads.append(thread)
但是,现实情况是您的代码存在其他严重问题,一旦您尝试将代码扩展到最低限度,这些问题可能会立即产生其他问题,这也是因为 Qt 在实现使用子类编程;即使 pyqtSlot
装饰器(通常是不必要的)也只有在 QObject 子类的 方法 上设置时才能正确工作。
通常不鼓励只使用匿名函数,因为它们不能直接引用它们必须使用的实例。此外,您的 run()
函数是错误的,因为它没有 self
参数,这将导致崩溃。
您的代码的更好版本可能与此类似:
class LoginWindow(QtWidgets.QWidget, Ui_Form1):
def __init__(self, listenThread):
super().__init__()
self.setupUi(self)
self.pushButton.clicked.connect(listenThread.start)
class ChatWindow(QtWidgets.QWidget, Ui_Form):
def __init__(self, listenThread, loginWindow):
super().__init__()
self.listenThread = listenThread
self.loginWindow = loginWindow
self.setupUi(self)
self.listenThread.listen_var.connect(self.update_chat_history)
def update_chat_history(self, message):
print(message)
self.textEdit_2.append(message)
def send_pressed(self):
message = self.loginWindow.lineEdit.text() + ' > ' + self.lineEdit.text()
sock.send(bytes(str(message),'utf-8'))
self.lineEdit.setText('')
class ListenThread(QtCore.QThread):
listen_var = QtCore.pyqtSignal(str)
def run(self):
print('checkpoint')
while True:
listen_var.emit('message')
QtCore.QThread.msleep(1000)
listenThread = ListenThread()
loginWindow = LoginWindow(listenThread)
chatWindow = ChatWindow(listenThread, loginWindow)
sys.exit(app.exec_())
我正在制作迷你聊天应用程序以提高我在 Python 中的套接字和 GUI 技能。但是每次我启动应用程序时,我的 QThread 都在倾倒。 我需要 运行 带 GUI 的线程 这是client.py
import socket
import sys
from colorama import Fore, Back, Style
from os import system, name
import sys
from chat import Ui_Form as Ui_Form
from login import Ui_Form as Ui_Form1
from PyQt5 import QtCore, QtGui, QtWidgets
from threading import Thread
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
app = QtWidgets.QApplication(sys.argv)
Form_login = QtWidgets.QWidget()
ui_login = Ui_Form1()
ui_login.setupUi(Form_login)
Form_login.show()
Form_chat = QtWidgets.QWidget()
ui_chat = Ui_Form()
ui_chat.setupUi(Form_chat)
history = ''
class listen_thread(QtCore.QObject):
running = False
listen_var = QtCore.pyqtSignal(str)
def run():
print('checkpoint')
while True:
listen_var.emit('message')
QtCore.QThread.msleep(1000)
def connect_pressed():
username = ui_login.lineEdit.text()
Form_login.hide()
Form_chat.show()
sock.connect(('127.0.0.1', 10000))
thread = QtCore.QThread()
listen1 = listen_thread()
listen1.moveToThread(thread)
listen1.listen_var.connect(update_chat_history)
thread.started.connect(listen1.run)
thread.start()
@QtCore.pyqtSlot(str)
def update_chat_history(message):
print(message)
ui_chat.textEdit_2.append(message)
def send_pressed():
message = ui_login.lineEdit.text() + ' > ' + ui_chat.lineEdit.text()
sock.send(bytes(str(message),'utf-8'))
# update_chat_history(message)
ui_chat.lineEdit.setText('')
def listen(some):
while True:
try:
data = sock.recv(1024)
except:
pass
else:
update_chat_history(str(data))
ui_login.pushButton.clicked.connect(connect_pressed)
ui_chat.pushButton.clicked.connect(send_pressed)
sys.exit(app.exec_())
当我启动它时,输出是:
QThread: Destroyed while thread is still running
Aborted (core dumped)
有人可以帮忙吗???
你的问题的解释很简单:在 connect_pressed
中创建的线程在该函数之外没有引用,因此一旦函数 returns.
“简单”的解决方案是在该函数之外创建线程,并且 运行 仅在该处创建线程,或者将线程添加到容器(例如,列表)中:
threads = []
def connect_pressed():
# ...
threads.append(thread)
但是,现实情况是您的代码存在其他严重问题,一旦您尝试将代码扩展到最低限度,这些问题可能会立即产生其他问题,这也是因为 Qt 在实现使用子类编程;即使 pyqtSlot
装饰器(通常是不必要的)也只有在 QObject 子类的 方法 上设置时才能正确工作。
通常不鼓励只使用匿名函数,因为它们不能直接引用它们必须使用的实例。此外,您的 run()
函数是错误的,因为它没有 self
参数,这将导致崩溃。
您的代码的更好版本可能与此类似:
class LoginWindow(QtWidgets.QWidget, Ui_Form1):
def __init__(self, listenThread):
super().__init__()
self.setupUi(self)
self.pushButton.clicked.connect(listenThread.start)
class ChatWindow(QtWidgets.QWidget, Ui_Form):
def __init__(self, listenThread, loginWindow):
super().__init__()
self.listenThread = listenThread
self.loginWindow = loginWindow
self.setupUi(self)
self.listenThread.listen_var.connect(self.update_chat_history)
def update_chat_history(self, message):
print(message)
self.textEdit_2.append(message)
def send_pressed(self):
message = self.loginWindow.lineEdit.text() + ' > ' + self.lineEdit.text()
sock.send(bytes(str(message),'utf-8'))
self.lineEdit.setText('')
class ListenThread(QtCore.QThread):
listen_var = QtCore.pyqtSignal(str)
def run(self):
print('checkpoint')
while True:
listen_var.emit('message')
QtCore.QThread.msleep(1000)
listenThread = ListenThread()
loginWindow = LoginWindow(listenThread)
chatWindow = ChatWindow(listenThread, loginWindow)
sys.exit(app.exec_())