Lỗi QObject: Cannot create children for a parent that is in a different thread

Mình có một đoạn code PyQt5 như sau

from PyQt5 import QtCore, QtGui, QtWidgets
from random import seed, randint
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from final import Ui_DataDisplay  # importing our generated file

import paho.mqtt.client as mqtt

import mysql.connector
from mysql.connector import Error

import socket
from threading import Thread 
from socketserver import ThreadingMixIn 

HOST = '127.0.0.1'  # Standard loopback interface address (localhost)
PORT = 8888        # Port to listen on (non-privileged ports are > 1023)

import sys


import paho.mqtt.client as mqtt

seed(1)

class mywindow(QtWidgets.QMainWindow):
	def __init__(self):
		super(mywindow, self).__init__()
		self.ui = Ui_DataDisplay()
		self.ui.setupUi(self)

	# def update_label_esp(self):
	# 	self.ui.textBrowser_3.setText("ok")

	# def update_label_esp2(self):
	# 	self.ui.textBrowser_4.setText("ok 2")

	def update_label(self):
		update = randint(0, 10)
		self.ui.textBrowser.setText(str(update))
		mySQLconnection = mysql.connector.connect(host='localhost',
                             database='testdb',
                             user='root',
                             password='22trannho')
		sql_select_Query = "SELECT * FROM rpi WHERE ID=2"
		cursor = mySQLconnection .cursor()
		cursor.execute(sql_select_Query)
		records = cursor.fetchall()
		for row in records:
			self.ui.textBrowser_2.setText(str(row[1]))		
		# self.update = update.label_update(self)

class ServerThread(Thread):
	def __init__(self,window): 
		Thread.__init__(self) 
		self.window=application

 
	def run(self): 
     
		tcpServer.listen(4) 
		# conn, addr = tcpServer.accept() 

		while True:
			print("Multithreaded Python server : Waiting for connections from TCP clients...") 
			global conn
			(conn, (ip,port)) = tcpServer.accept() 
			newthread = ClientThread(ip,port,application) 
			newthread.start() 
			threads.append(newthread)
		for t in threads:
			t.join()  


class ClientThread(Thread): 

	def __init__(self,ip,port,window): 
		Thread.__init__(self) 
		self.window=application
		self.ip = ip 
		self.port = port 
		print("[+] New server socket thread started for " + ip + ":" + str(port)) 
 
	def run(self):
		while True :   
			#(conn, (self.ip,self.port)) = serverThread.tcpServer.accept() 
			global conn
			data = conn.recv(2048) 
			# test.chat.append(data.decode("utf-8"))
			if not data: 
				break
			print(data)
			application.ui.textBrowser_3.setText(data.decode("utf-8"))

		print("Client disconnect")

		# close socket server
		serverThread=ServerThread(application)
		serverThread.start()

        # while True : 
            
        #     #(conn, (self.ip,self.port)) = serverThread.tcpServer.accept() 
        #     global conn
        #     data = conn.recv(2048) 
        #     # window.chat.append(data.decode("utf-8"))
        #     print(data)


if __name__ == '__main__':
	app = QtWidgets.QApplication([])
	application = mywindow()
	# application.update_label_esp()
	application.show()
	# timer = QTimer()
	# timer.timeout.connect(application.update_label)
	# timer.start(2000)
	# application.update_label_esp()

	TCP_IP = '127.0.0.1' 
	TCP_PORT = 8888 
	BUFFER_SIZE = 20  
	tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
	tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
	tcpServer.bind((TCP_IP, TCP_PORT)) 
	threads = []     
	    
	serverThread=ServerThread(application)
	serverThread.start()
	# application.exec_()  
	sys.exit(app.exec_())

Ý đồ của mình là khi nhận được socket từ client thì sẽ cập nhật thông tin cho textBrowser_3, tuy nhiên thì lại bị lỗi

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTextDocument(0x17b79c0), parent's thread is QThread(0x116e3d0), current thread is QThread(0x7fda880012e0)
Segmentation fault (core dumped)

Lúc đầu mình làm bình thường chứ ko có Thread vẫn bị, giờ đổi lại thì vẫn bị

Cảm ơn mọi người rất nhiều !

Mình nghĩ là do mình imort file giao diện qua để setup Ui nên nó ko đổi được
Mình thử đổi title window thôi thì vẫn được

Có lẽ là serverThread và QtWidgets.QApplication ở 2 thread khác nhau nên sinh ra lỗi này.
Bạn thử dùng event signals & slots của qt để setText

Mình cũng có tham khảo qua nhưng cũng ko biết nên làm thế nào nữa ?

Tương tự như vậy

from random import seed, randint
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

import socket
from threading import Thread
from socketserver import ThreadingMixIn

HOST = '127.0.0.1'  # Standard loopback interface address (localhost)
PORT = 8888  # Port to listen on (non-privileged ports are > 1023)

import sys

seed(1)


class mywindow(QWidget):
    signal = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 thread-safe'
        self.left = 10
        self.top = 10
        self.width = 320
        self.height = 200
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.textBrowser = QTextBrowser(self)
        self.textBrowser.setOpenExternalLinks(True)
        self.textBrowser.setObjectName("textBrowser_3")
        self.signal.connect(self.handle_trigger)
        self.show()

    @pyqtSlot(str)
    def handle_trigger(self, value):
        self.textBrowser.setText(value)


class ServerThread(Thread):
    def __init__(self, window):
        Thread.__init__(self)
        self.window = window

    def run(self):

        tcpServer.listen(4)
        # conn, addr = tcpServer.accept()

        while True:
            print("Multithreaded Python server : Waiting for connections from TCP clients...")
            global conn
            (conn, (ip, port)) = tcpServer.accept()
            newthread = ClientThread(ip, port, application)
            newthread.start()
            threads.append(newthread)
        for t in threads:
            t.join()


class ClientThread(Thread):

    def __init__(self, ip, port, window):
        Thread.__init__(self)
        self.window = window
        self.ip = ip
        self.port = port
        print("[+] New server socket thread started for " + ip + ":" + str(port))

    def run(self):
        while True:
            # (conn, (self.ip,self.port)) = serverThread.tcpServer.accept()
            global conn
            data = conn.recv(2048)
            # test.chat.append(data.decode("utf-8"))
            if not data:
                break
            print(data)
            self.window.signal.emit(data.decode("utf-8"))

        print("Client disconnect")

        # close socket server
        serverThread = ServerThread(application)
        serverThread.start()

    # while True :

    #     #(conn, (self.ip,self.port)) = serverThread.tcpServer.accept()
    #     global conn
    #     data = conn.recv(2048)
    #     # window.chat.append(data.decode("utf-8"))
    #     print(data)


if __name__ == '__main__':
    app = QApplication([])
    application = mywindow()
    # application.update_label_esp()
    application.show()
    # timer = QTimer()
    # timer.timeout.connect(application.update_label)
    # timer.start(2000)
    # application.update_label_esp()

    TCP_IP = '127.0.0.1'
    TCP_PORT = 8888
    BUFFER_SIZE = 20
    tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    tcpServer.bind((TCP_IP, TCP_PORT))
    threads = []

    serverThread = ServerThread(application)
    serverThread.start()
    # application.exec_()
    sys.exit(app.exec_())
1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?