QApplication In Non-Main Thread

warning: qapplication was not created in the main() thread
qthread
pyqt5 threading

I need to exec() a QApplication in a thread that is not main (my GUIs must be plugins that can be dynamically loaded and unloaded at runtime, so I have no access to the main thread). Does anyone know of a (relatively) painless way to hack around Qt's restriction against starting QApplication outside of main?

I'm developing in Linux with Qt4 in C++ using gcc4.3.4.

If you are using QThread then you already have normal Qt event loop and can just run exec() inside QThread::run() function. While you can't work with GUI objects outside of the main thread you still can interact with them through queued signal/slot connections. Maybe you can try to store pointer to the main thread QThread object and call QObject::moveToThread() to move your GUI objects to the main thread instead of moving QApplication into another thread.

I think it's not really good idea to try to go against toolkit with different kind of hacks and kluges.

QApplication in non-main thread, Hi! I'm trying to write a lib based on Qt that'd have QApplication running in a separate thread. The idea is to have these exported functions (to  When using Matplotlib with the multiprocessing module, QApplication and QObject warnings appear on the console, related to the fact that the plots are not issued from the main thread. My guess is that the callback gets executed on a separate thread, and the Matplotlib backend does not like this.

You can start a QApplication in a PThread as below

//main.cpp
#include <iostream>
#include "appthread.h"
int main(int argc, char *argv[]) {
  InputArgs args = {argc, argv};
  StartAppThread(args);
  sleep(10);
  return 0;
}
//appthread.h
struct InputArgs{
  int argc;
  char **argv;
};
void StartAppThread(InputArgs &);
//appthread.cpp
#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include "appthread.h"
#include <pthread.h>

void *StartQAppThread(void *threadArg) {
  InputArgs *args = (struct InputArgs*) threadArg;
  QApplication app(args->argc, args->argv);
  QMainWindow w;
  w.show();
  w.setCentralWidget(new QPushButton("NewButton"));
  app.exec();
  pthread_exit(NULL);
}

void StartAppThread(InputArgs &args) {
  pthread_t thread1;  
  int rc = pthread_create(&thread1, NULL, StartQAppThread, (void*)&args);
}

Starting QT GUI in a seperate Thread, hpgeUI(argv); //this function does all the QApplication, exec() stuff you can't create widgets in a non-GUI thread, the GUI-thread is main the thread. you need to  Based on the Qt docs and other examples on the web, I would have thought that the following program, which uses QThread.started signal, would start workers in non-main threads. But this is not the case, instead each work slot is called from main thread:

Ok, I got something that works! It's not pretty, but it definitely does the job.

  1. Create a QMainWindow derivative with all of your actual GUI code in it and overload the event() function of this class to call this->show()

  2. Create a class (let's call it Runner) which will hold a pointer to your QMainWindow derivative, and give it a run function.

  3. In the Runner::Runner(), start up a thread which will call Runner::run()

  4. In Runner::run() (which is now running in it's own thread) construct a QApplication, and an instantiation of your QMainWindow derivative. Call the exec() function of the QApplication.

  5. Now, when you want to start up your GUI, just post any event to your QMainWindow derivative, and it will show itself!

This solution seems to work very well in Linux, although it really seems to be exploiting some loophole in Qt and may not work on other platforms. Definitely easier than patching Qt though.

Create QMainWindow from different thread, One non QObject-Object should represent a QMainWindow to cut the bindings to Qt. I cannot create a widget -> I tried new QApplication(c, NULL); But this is not working without a call in the main thread line 37  When running an unmodified version of same game on Android, you can get the "QApplication is not created on main thread" warning. This indicates that something has called QThread::currentThread() before initializing the Q*Application, causing the Android main thread to be registered instead of the Qt main thread.

Patch Qt, I guess and remove the main thread check, and test if that works for you. According to http://bugreports.qt-project.org/browse/QTBUG-7393 that won't work on OS X/Cocoa though, as Cocoa assumes the first thread spawned to be the main/UI thread.

How to avoid Qt app.exec() blocking main thread, I found this: QApplication In Non-Main Thread. and those solutions gave me some different behavior. In the right direction, but not stable or fully functional. So, let's call "Thread A" the thread that executes the public method of my library, that performs the three lines above. A new thread is created (the "boost" one), called "Thread B", that creates an instance of QApplication, my DialogProvider, and executes event loop of QApplication, everything in the same context.

Adding my 2 cents with a fancy lambda and C++ threads:

#include "mainwindow.h"
#include <QApplication>
#include <thread>

int main(int argc, char *argv[])
{
    std::thread t1
    (
        [&]
        {
            QApplication a(argc, argv);
            MainWindow w;
            w.show();
            return a.exec();
        }
    );
    t1.join();
}

Here Mainwindow can be your QMainWindow.

Communicating with the Main Thread, When a Qt application starts, only one thread is running—the main thread. This is the only thread that is allowed to create the QApplication or  self.get_thread = getPostsThread(subreddit_list) self.connect(self.get_thread, SIGNAL("finished()"), self.done) self.get_thread.start() It's pretty straightforward, and the only difference between that and a custom signal is that we'll have to define custom signal in the QThread class, but the code used in the main thread stays the same.

Matplotlib + multiprocessing: WARNING: QApplication was not , WARNING: QApplication was not created in the main() thread. So I would argue that, if Qt has issues with non-main threads, then the Qt 

Multithreading PyQt applications with QThreadPool (Updated 2020 , Run background tasks concurrently without impacting your UI :::python app = QApplication([]) window = MainWindow() app.exec_() The thread which runs this event loop — commonly referred to as the GUI thread — also Lock (GIL) — meaning non-GIL-releasing Python code can only execute in one thread at a time​.

Qt 4.8: Threading Basics, This thread is called the "main thread" (also known as the "GUI thread" in Qt is usually no concurrent access to methods, calling non-thread-safe methods of objects in int main(int argc, char *argv[]) { QApplication app(argc, argv); // build gui 

Comments
  • I think you may be right, VestniK - While my GUI does indeed run, it doesn't seem to actually service update() calls unless I force the OS to redraw the GUI by dragging another window around on top of it.
  • I found this answer useful for solving another problem, but while moving QMainWindow object from another thread to main one I received QObject::moveToThread: Widgets cannot be moved to a new thread
  • Hey Boatzart, I am trying to achieve the same thing. When you say " the Runner::Runner(), start up a thread which will call Runner::run()", what do you mean. Start another QThread which would start Runner thread? But how could you start another thread without constructing QApplication?