繁体   English   中英

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_())

当我启动它时,output 是:

QThread: Destroyed while thread is still running
Aborted (core dumped)

有人可以帮忙吗???

您的问题的解释很简单:在connect_pressed中创建的线程在 function 之外没有引用,因此一旦 function 返回,它就会立即被垃圾收集。

“简单”的解决方案是在 function 之外创建线程并仅在那里运行线程,或者将线程添加到容器(例如列表):

threads = []

def connect_pressed():
    # ...
    threads.append(thread)

但是,现实情况是,您的代码还有其他严重的问题,一旦您尝试最小限度地扩展代码,这可能会产生其他问题,这也是因为 Qt 在使用子类实现程序时更容易处理; 即使是pyqtSlot装饰器(通常是不必要的)也只有在 QObject 子类的方法上设置时才能正常工作。

通常不鼓励只使用匿名函数,因为它们不能直接引用它们必须使用的实例。 此外,您的run() function 是错误的,因为它没有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_())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM