Issue
I am making mini chat application to improve my socket and GUI skills in Python. But my QThread is dumping every time when I'm launching application. I need to run Thread with GUI Here it is 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_())
When I'm launching it the output is:
QThread: Destroyed while thread is still running
Aborted (core dumped)
Can somebody help???
Solution
The explanation of your problem is simple: the thread created in connect_pressed
has no reference outside that function, so it gets immediately garbage collected as soon as the function returns.
The "simple" solution would be to create the thread outside of that function and run the thread only there, or add the thread to a container (for instance, a list):
threads = []
def connect_pressed():
# ...
threads.append(thread)
But, the reality, is that your code has other serious issues, which would probably create other problems as soon as you try to expand your code even minimally, and that's also because Qt is easier to deal with when implementing the program using subclasses; even the pyqtSlot
decorator (which is normally unnecessary) can only correctly work if it's set on a method of a QObject subclass.
Using only anonymous functions is usually discouraged, as they cannot have a direct reference to instances they must work with. Also, your run()
function is wrong, as it doesn't have the self
argument, which will result in a crash.
A better version of your code could be similar to this:
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_())
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.