Issue with QMainWindow instance access



  • Hi,

    I'm having an OO-programming issue when trying to access functions contained in the class derived from QMainWindow.

    Here are the simplified corresponding parts of my code :

    In mainwindow.h :

    class MainWindow : public QMainWindow
    {
    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    public:
    void theFunctionIWantToCallOnWindowInstance();

    private:
    Ui::MainWindow *ui;

    In mainwindow.cpp :

    void MainWindow::theFunctionIWantToCallOnWindowInstance()
    {
    QMessageBox::information(this, "[DEBUG]", "theFunctionIWantToCallOnWindowInstance() called");
    }

    In main.cpp file :

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

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
    }

    In external.cpp :

    Basically, I simply want to call a function from external code on the window instance created in main.cpp, something like :

    #include "mainwindow.h"
    ...
    MainWindow::getInstanceCreatedInMain().theFunctionIWantToCallOnWindowInstance();

    I tried many different approaches using singletons and static (and even global) variables but I cannot solve my problem i.e. get a reference to my window from the external code.

    Thanks in advance for your help.

    Michael



  • @MichaelM said:

    getInstanceCreatedInMain

    Where is the getInstanceCreatedInMain defined?


  • Moderators

    Hi and welcome,

    Using globals or calling a method of a main window deep in your code are signs of flawed design. There's usually no (good) reason to do that. You could, for example, emit a signal and connect that to the main window. This way you won't create a coupling, where a child needs to know about its parent.

    To answer your question and tell you how to shoot yourself in the foot - here's how you would make your single instance of main window accessible from anywhere in the code:

    //mainwindow.h
    class MainWindow : public QMainWindow
    {
       ...
    public:
       static MainWindow* instance();
    private:
       static MainWindow* s_instance;
    };
    
    //mainwindow.cpp
    static MainWindow* MainWindow::s_instance = nullptr;
    
    MainWindow* MainWindow::instance() { return s_instance; }
    
    MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
    {
       assert(!s_instance); //another instance already exists!
       s_instance = this;
    }
    

    Then you can reference the main window from anywhere like this:

    MainWindow::instance()->doWhatever();
    

    Just to repeat - I advise against using this. You have a case of inverted relation in your design and it would be better to look into that.



  • Thanks a lot for your help.
    I finally managed to solve my problem by using your method. I know about coupling but for some reasons I cannot change the structure / design of external.cpp.

    Just a detail, in the code you provided I had to replace :

    //mainwindow.cpp
    static MainWindow* MainWindow::s_instance = nullptr;

    By :

    //mainwindow.cpp
    MainWindow* MainWindow::s_instance = nullptr;

    as it throws the compilation error :
    error: 'static' may not be used when defining (as opposed to declaring) a static data member [-fpermissive]


Log in to reply
 

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