Viatorus
Viatorus

Reputation: 1903

Create QMainWindow from different thread

I try to create something like a window pool. You can use these windows everywhere in your program to display graphics and plot diagrams etc. The widgets working well but the main problem at the moment is the frustrated tries, to create the pool. One non QObject-Object should represent a QMainWindow to cut the bindings to Qt.

I cannot create a widget -> I tried invokeMethode, connect and QTimer but nothing works. Sometimes the methods don´t get called or I am not in the gui thread... Any idea?

Edit 2 - new version:

header:

#pragma once
#include <QMainWindow>
#include <QTimer>

class MyWindow : QObject
{
  Q_OBJECT
public:
  MyWindow();
};

class QWindowPool : public QObject
{
  Q_OBJECT
 public:
   QWindowPool();
 public slots:
  void createWindow();  
};

class QWindow : public QMainWindow
{
  Q_OBJECT
};

cpp: #include

#include <QApplication>
#include <QTimer>
#include <QtConcurrent/qtconcurrentrun.h>

#include <iostream>
#include <future>

static QWindowPool *pool = new QWindowPool();

QWindowPool::QWindowPool() {

  // check if app is running
  if (!QApplication::instance()) {
    bool appOnline = false;
    QtConcurrent::run([&appOnline](){
      int c = 0;
      new QApplication(c, NULL);
      appOnline = true;
      qApp->exec();
    });
    while (!appOnline) {}
  }
  moveToThread(QApplication::instance()->thread());
}

void QWindowPool::createWindow() {
  printf("window created\n");
  new QWindow();
}

MyWindow::MyWindow() {
  QTimer::singleShot(0, pool, SLOT(createWindow()));
}

int main()
{
  MyWindow mw;
  std::thread t1([](){
    MyWindow mw;

    std::thread t2([](){
      MyWindow mw;
    });

    t2.join();
  });
  t1.join();

  std::cin.ignore();
  return 0;
}

Now the code do what is should. I can create widgets in different threads. But there are two scenarios, where I would stack at:

What I want is in the final application: The user should get the possibility to write anywhere in his code and in any thread:

MyWindow mw(dataToDisplay)

and the window should be created and showed to him.

Upvotes: 0

Views: 1518

Answers (1)

SingerOfTheFall
SingerOfTheFall

Reputation: 29986

Qt will only let you create widgets from the main GUI thread, this is explicitly mentioned in the docs (emphasis mine):

As mentioned, each program has one thread when it is started. This thread is called the "main thread" (also known as the "GUI thread" in Qt applications). The Qt GUI must run in this thread. All widgets and several related classes, for example QPixmap, don't work in secondary threads. A secondary thread is commonly referred to as a "worker thread" because it is used to offload processing work from the main thread.

Upvotes: 1

Related Questions