I'm creating a chat app with PyQt and socketio.
Whenever I want to add a new message widget to the scroll area this error appears "QObject::setParent: Cannot set parent, new parent is in a different thread"
This is my code:
import sys
from html import escape
from socketio import Client
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QWidget, QScrollArea, QVBoxLayout,
QLabel, QLineEdit, QPushButton)
class Message(QWidget):
def __init__(self, sender, text):
super().__init__()
layout = QVBoxLayout()
self.setLayout(layout)
senderLbl = QLabel(sender)
layout.addWidget(senderLbl)
layout.addWidget(QLabel(text))
class ChatField(QScrollArea):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setWidgetResizable(True)
widget = QWidget()
self.layout = QVBoxLayout()
widget.setLayout(self.layout)
self.setWidget(widget)
for x in range(50):
self.layout.addWidget(Message('sender', 'text'))
def addMessage(self, sender, text):
self.layout.addWidget(Message(sender, text))
class App(QWidget):
def __init__(self):
super().__init__()
self.connected = False
layout = QVBoxLayout()
self.setLayout(layout)
self.output = ChatField(self)
self.input = QLineEdit()
self.input.returnPressed.connect(self.send_message)
self.input.setEnabled(False)
layout.addWidget(self.output)
layout.addWidget(self.input)
self.setWindowTitle('MyChat-Connecting...')
self.show()
def send_message(self):
sio.emit('send_message', {'username':'anonymouse', 'message':self.input.text()})
app = QApplication([])
sio = Client()
window = App()
@sio.event
def connect():
window.setWindowTitle('MyChat')
window.input.setEnabled(True)
@sio.event
def get_message(data):
window.output.addMessage(data['from'], data['message'])
sio.connect('http://localhost:8080')
sys.exit(app.exec_())
and this is my server code:
from socketio import AsyncServer
from aiohttp.web import Application, run_app
app = Application()
sio = AsyncServer(async_mode='aiohttp')
sio.attach(app)
@sio.event
async def connect(sid, environ, auth):
sio.enter_room(sid, 'chat-room')
print('user', sid, 'has joined the chat')
@sio.event
async def disconnect(sid):
sio.leave_room(sid, 'chat-room')
print('user', sid, 'has left the chat')
@sio.event
async def send_message(sid, data):
await sio.emit('get_message', {'from':data['username'], 'message':data['message']}, room='chat-room')
run_app(app, port=8080)
I can't understand why does it happen and I'm not using any other thread.