2011-11-25 53 views
0

我正在开发一个聊天程序,其中客户端是单线程的,但服务器将为每个连接的客户端启动一个新线程。我相信我的客户端代码是稳定的,但服务器让我感到困惑。如何从QThread启动GUI窗口?

现在,我有一个派生的QTcpSocket类查找传入连接,当它看到一个,开始一个新的QThread。当QThread运行时,它会创建一个QMainWindow(它是聊天窗口)的实例并显示它。

void secureserver::incomingConnection(int socketDescriptor) 
{ 
    securethread *thread = new securethread(socketDescriptor, this); 
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); 
    thread->start(); 
} 

void securethread::run() 
{ 
    serverwindow myServerWindow; 
    myServerWindow.setSocketDescriptor(mySocket); 
    myServerWindow.show(); 
} 

我已经得到错误stderror像下面,和QMainWindow永远不会出现这样聊着在这一点上是不可能的。

QObject: Cannot create children for a parent that is in a different thread. 
(Parent is QApplication(0xbf9e5358), parent's thread is QThread(0x98a54f0), current thread is securethread(0x99e9250) 
QPixmap: It is not safe to use pixmaps outside the GUI thread 

我的问题是:

  • 我需要做的QThreadQMainWindow父母?
  • 我是以完全错误的方式去谈论这个吗?
  • 任何其他一般的想法,为什么这不工作,因为我期望它 或如何解决它将不胜感激。
+0

我很困惑,为什么你的服务器有任何GUI代码在所有。在我看来,你的客户端应该是显示聊天窗口的客户端,而服务器应该是纯粹的将消息从一个客户端传递到另一个客户端的机制。 – Chris

+0

这个想法是,你有许多客户端,一台服务器(一个本地IP地址和端口),但服务器为每个传入连接创建一个新线程。然后,服务器可以在每个窗口中仅有一个客户端进行通信,但它可以同时在这些新线程/窗口中发送/接收,因为它们将处于其自己的线程中。我没有设计这个程序的规格,所以我和你一起问为什么。 – J2N

回答

1

是的,你正在以错误的方式去解决这个问题。由于平台限制,GUI是单线程系统。你不能在不同的线程上创建,更改和管理GUI对象 - 一切都必须在一个线程上完成(通常是GUI线程)。

Qt有两种处理工作线程和GUI的机制:排队信号和插槽,以及QCoreApplication :: postEvent()处理程序。

更多详情,全面Qt的线程文件:http://doc.qt.io/qt-5/thread-basics.html

+0

嗯,你有什么建议为每个传入的客户端连接打开一个新窗口吗? 这是对服务器是多线程的项目的一个要求,并且每个试图聊天的客户端都会弹出一个新的聊天窗口,以便多个客户端可以同时与服务器进行通信。 – J2N

+0

@JLaw:线程可以处理I/O和消息,但是所有的GUI活动都需要在一个线程上完成。您应该使用排队信号/插槽机制与UI进行通信,而不是混合服务器代码和UI代码。 –

+0

这很有道理,我可以使用信号和插槽。我仍然唯一想知道的是,我需要为每个客户端单独弹出一个窗口。我仍然可以使用我的incomingConnection函数来创建GUI窗口和线程的新实例,并使用该线程和窗口之间的信号/插槽? – J2N