gpt4 book ai didi

python - PyQt5 : Destroyed while thread is still running

转载 作者:行者123 更新时间:2023-12-03 12:02:03 25 4
gpt4 key购买 nike

试图添加异常,断开服务器连接时程序(客户端)应该做什么。
这个想法很简单。如果服务器已关闭-客户端应尝试连接到服务器,直到服务器打开为止。
服务器关闭时-程序尝试连接。但是,当我打开服务器电源时,客户端已连接,并且该连接断开后,在客户端应用程序中我看到了-QThread:线程仍在运行时被破坏了
这是我想要的简单示例(客户端的最小可复制示例):

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
import socket


class ListeningThread(QtCore.QThread):
mysignal = QtCore.pyqtSignal(str)
def __init__(self, server_socket, parent=None):
QtCore.QThread.__init__(self, parent)
self.server_socket = server_socket
self.message = None

def run(self):
try:
while True:
self.message = self.server_socket.recv(4096)
self.mysignal.emit(self.message.decode('utf-8'))
except:
Push()

class Push(QtWidgets.QMainWindow):
def __init__(self):
super(Push, self).__init__()
print('now connecting...')
self.connect_server()
def connect_server(self):
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.server_socket.connect(('127.0.0.1', 5555))
self.message_monitor = ListeningThread(self.server_socket)
self.message_monitor.mysignal.connect(self.init_UI)
self.message_monitor.start()
except:
Push()

def init_UI(self, message):
print(message)

app =QtWidgets.QApplication([])
application = Push()
sys.exit(app.exec_())
我在ListeningThread中尝试过:
 class ListeningThread(QtCore.QThread):
mysignal = QtCore.pyqtSignal(str)
def __init__(self, server_socket, parent=None):
QtCore.QThread.__init__(self, parent)
self.server_socket = server_socket
self.message = None

def run(self):
try:
while not self.isInterruptionRequested():
self.message = self.server_socket.recv(4096)
self.mysignal.emit(self.message.decode('utf-8'))
except:
print('error in thread')
self.requestInterruption()
self.wait()
Push()
但是问题仍然是一样的。
我想我应该在Push.connect_server中启动之前关闭线程,但是idk怎么做。
对于最小的可复制示例,您可以使用该服务器:
import socket
import threading

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('127.0.0.1', 5555))
server_socket.listen()
clients = []

def accept_socket():
while True:
client_socket, addr = server_socket.accept()
print(f'connection from {addr}')
print(client_socket)
if client_socket not in clients:
clients.append(client_socket)

def sending_message(clients, data):
for client_socket in clients:
try:
client_socket.send(data.encode("utf-8"))
except:
pass

accept_thread = threading.Thread(target= accept_socket)
accept_thread.start()


while True:
data = input('Enter_message:\n')
sending_message(clients, data)

最佳答案

问题是,发生异常时,您正在创建一个范围有限的新“Push”对象,因为它是局部变量,因此将被销毁,并且诸如线程之类的对象也将被销毁,这就是它的作用。表示。错误消息。
可以使用QTcpSocket而不是使处理线程复杂化(IMO是它们的最后选择),它允许使用简单的方式通过信号处理套接字,并使用Qt eventloop。

from functools import cached_property
import sys

from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork


class Client(QtCore.QObject):
messageChanged = QtCore.pyqtSignal(str)

def __init__(self, parent=None):
super().__init__(parent)
self.socket.stateChanged.connect(self.handle_state_changed)
self.socket.errorOccurred.connect(self.handle_error_occurred)
self.socket.readyRead.connect(self.handle_ready_read)

@cached_property
def socket(self):
return QtNetwork.QTcpSocket()

def try_connect(self):
self.socket.connectToHost("127.0.0.1", 5555)

def handle_state_changed(self, state):
print(f"state: {state}")
if state == QtNetwork.QAbstractSocket.UnconnectedState:
print("disconnected")
QtCore.QTimer.singleShot(1000, self.try_connect)
elif state == QtNetwork.QAbstractSocket.ConnectedState:
print("connected")

def handle_error_occurred(self, error):
print(f"error code {error}, message: {self.socket.errorString()}")

def handle_ready_read(self):
codec = QtCore.QTextCodec.codecForName("UTF-8")
message = codec.toUnicode(self.socket.readAll())
self.messageChanged.emit(message)


class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)

self.client.messageChanged.connect(self.handle_message_changed)
self.client.try_connect()

@cached_property
def client(self):
return Client()

def handle_message_changed(self, message):
print(f"client message: {message}")


def main():

app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())


if __name__ == "__main__":
main()

关于python - PyQt5 : Destroyed while thread is still running,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65491018/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com