我有一个简单的服务器-客户端聊天程序,在其中我使用线程在后台从服务器接收数据。问题是当客户端收到消息时,必须为聊天创建一个新标签。但是我在线程中接收数据,因此可以检查数据并在线程中创建数据。因为我的窗口在主线程中,所以我无法创建窗口小部件并设置其父窗口。所以看起来像这样:
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
我了解这种情况的发生方式和原因,但我没有解决方案。有人可以帮我吗?
预先感谢...
答案 0 :(得分:0)
您不应从另一个线程修改(理解也要创建)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)