如何在非主线程中创建GUI小部件

2024-09-30 20:24:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个简单的服务器客户端聊天程序,在这个程序中,我使用线程在后台接收来自服务器的数据。问题是当客户端收到消息时,必须为聊天创建一个新的选项卡。但是我在线程中接收数据,这样我就可以检查数据并在线程中创建一个。除了我不能创建一个小部件并设置它的父窗口我的窗口,因为我的窗口在主线程中。所以看起来是这样的:

class MainWindow(QWidget):
    ...
        def addChatTab(self, nick, target, parent):
            tab = ChatTab(target)
            tab.setParent(parent)  #where I get the eror
            self.chatTabWidget.addTab(tab, nick)
            self.chatTabs[nick] = tab


class ServerManagement():
    ...
    def clientLoop(self): #runs in a different thread
        ...
        if sender == settingsManager.getUserNick():
            targetTab = receiver
        else:
            targetTab = sender

        if targetTab in mainWindow.chatTabs.keys():   #if tab is already there
            mainWindow.getChatTab(targetTab).write(message)
        else:
            mainWindow.addChatTab(targetTab, sender, mainWindow)     #create and add it to QTabWidget
            mainWindow.getChatTab(targetTab).write(message)

错误:

QObject::setParent: Cannot set parent, new parent is in a different thread

我知道这是怎么发生的,为什么会发生,但我只是没有解决办法。有人能帮我吗

提前谢谢


Tags: inself程序服务器客户端ifdeftab
1条回答
网友
1楼 · 发布于 2024-09-30 20:24:07

您不应该从另一个线程修改(理解并创建)GUI,其思想是通过信号发送次线程的信息,我们可以让ServerManagement从QObject继承,这样它就可以在ServerManagement的一个对象和MainWindow之间的一个公共范围内创建信号并建立连接:

class MainWindow(QWidget):
    # ...
    def addChatTab(self, nick, target, parent):
        tab = ChatTab(target)
        tab.setParent(parent)  #where I get the eror
        self.chatTabWidget.addTab(tab, nick)
        self.chatTabs[nick] = tab

    def foo_function(self, another_args)
       # ... foo function is the method where you create the Server Management object
       self.management = ServerManagement()
       self.management.targetChanged.connect(self.update_gui)
       #
    @pyqtSlot(str)
    def update_gui(self, targetTab):
        if targetTab in self.chatTabs.keys():   #if tab is already there
            self.getChatTab(targetTab).write(message)
        else:
            self.addChatTab(targetTab, sender, self)     #create and add it to QTabWidget
            self.getChatTab(targetTab).write(message)

class ServerManagement(QObject):
    targetChanged = pyqtSignal(str)
    def __init__(self, others_arguments):
        super(ServerManagement, self).__init__()
        # ...

    def clientLoop(self): #runs in a different thread
        # ...
        if sender == settingsManager.getUserNick():
            targetTab = receiver
        else:
            targetTab = sender
        self.targetChanged.emit(targetTab)

相关问题 更多 >