J2N
J2N

Reputation: 341

How can I start a GUI window from a QThread?

I'm working on a chat program where the client is single-threaded but the server will start a new thread for each connected client. I believe my client code is solid but the server has me bewildered.

Right now, I have a derived QTcpSocket class that looks for incoming connections and when it see's one, begins a new QThread. When the QThread runs, it creates an instance of a QMainWindow (which is the chat window) and shows it.

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();
}

I've been getting errors to stderror like the following, and the QMainWindow never appears so chatting is impossible at this point.

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

My questions are:

Upvotes: 0

Views: 1851

Answers (1)

Yann Ramin
Yann Ramin

Reputation: 33187

Yes, you are going about this in the wrong way. GUIs, due to platform limits, are single threaded systems. You cannot create, change and manage GUI objects on different threads - everything must be done on one thread (normally, the GUI thread).

Qt has two mechanisms for dealing with worker threads and the GUI: queued signals and slots, and the QCoreApplication::postEvent() handler.

More details are in the comprehensive Qt threading document: http://doc.qt.io/qt-5/thread-basics.html

Upvotes: 1

Related Questions