Как создать графический виджет в неосновной теме - PullRequest
1 голос
/ 11 марта 2019

У меня есть простая программа чата сервер-клиент, в которой я использую потоки для получения данных с сервера в фоновом режиме. Проблема в том, что когда клиент получает сообщение, необходимо создать новую вкладку для чата. Но я получаю данные в потоке, чтобы я мог проверить данные и создать их в потоке. За исключением того, что я не могу создать виджет и установить его родительское окно, потому что мое окно находится в главном потоке. Так это выглядит так:

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

Я понимаю, как и почему это происходит, но у меня просто нет решения для этого. Кто-нибудь может мне помочь?

Заранее спасибо ...

1 Ответ

0 голосов
/ 11 марта 2019

Вы не должны изменять (понимать и создавать) графический интерфейс из другого потока, идея состоит в том, чтобы посылать информацию о вторичном потоке через сигналы, чтобы мы могли сделать 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...