QWidget: Must construct a QApplication before a QWidget error



  • So I am trying to separate the instantiation of QApplication from main and put it in a class member function.

    I have a class that allows me to instantiate as many Qt windows as I want on a separate thread:

    class QtWindowInit: public QWidget {
    
      Q_OBJECT
    
    public:
    
      QtWindowInit(QWidget* parent = 0) { /* Initialize stuff */ }
    
      inline void Init() {
    
        boost::thread (StartThread());
    
      }
    
    private:
    
      inline void StartThread() {
    
        char *argv[] = {"program name", "arg1", "arg2", NULL};
        int argc = sizeof(argv) / sizeof(char*) - 1;
    
        QApplication app(argc, argv);
    
        // Code to initialize window and add QWidgets in here
    
        app.exec();
    
      }
    
      // Other class member variables here
    
    }
    

    Then I have other classes to use this QtWindowInit class to create a button for example. They do not depend on Qt, all the Qt is done in the QtWindowInit class

    class CreateButton {
    
    public:
    
      CreateButton() { /* Do stuff */ }
    
      // Other functions
    
    private:
    
      QtWindowInit _QtWindowInit; // Here is the problem
    
    }
    

    So the issue here is that the CreateButton class does not create a QApplication. When we create a CreateButton object it will then create a QtWindowInit object and will fail because QApplication has not been called yet and QtWindowInit constructor takes in the default QWidget* parent = 0 constructor. I end up with this error "QWidget: Must construct a QApplication before a QWidget". Anyone know how I can work around this problem?


  • Moderators

    Hi, and welcome to the Qt Dev Net!

    @justiliang said:

    Anyone know how I can work around this problem?

    Don't let QtWindowInit inherit QWidget (or even QObject, for that matter).

    There are two rules to follow:

    1. QApplication must be the first QObject created in your program.
    2. All GUI-related classes (QWidget, in particular) must be created in the same thread as QApplication, and all their methods must be called from that thread only.


  • I would also add to JKSH's answer that the docs state clearly:

    For any GUI application using Qt, there is precisely one QApplication object, no matter whether the application has 0, 1, 2 or more windows at any given time.
    This means that your classes using a QtWindowInit object are totally wrong because each QtWindowInit instance will create a new QApplication object+instance, which will conflict with the previous one(s) (they would not know which QApplication object should manage the events) -- unless you make it static, but then other problems arise, definitely thread unsafe.
    That's why in most Qt applications it is very often to find a QApplication (or QCoreApplication) object declaration in the very first lines of main(), and then forget about it at all.

    Although I am not a threads expert, I can think of creating a main thread containing the QApplication object and the methods to create new widgets. Then, in the other threads of your application, you should just give the main thread a hint on which widget to create.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.