Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to inherit from MainWindow in Qt?



  • I'd like to know how to do inheritance from MainWindow correctly. For example, program has a mainwindow with combobox, I want have a class which do some operations on this combobox: for example fill the combobox.

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class FillCombo;
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    

    fillcombo.h

    #ifndef FILLCOMBO_H
    #define FILLCOMBO_H
    
    #include <QMainWindow>
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    QT_BEGIN_NAMESPACE
    namespace Fill { class MainWindow; }
    QT_END_NAMESPACE
    
    class FillCombo:public MainWindow
    {
    public:
        FillCombo(QWidget *parent = nullptr);
        ~FillCombo();
    private:
        Fill::MainWindow *f_ui;
    };
    
    #endif // FILLCOMBO_H
    

    fillcombo.cpp

    #include "fillcombo.h"
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    
    FillCombo::FillCombo(QWidget *parent)
        : MainWindow(parent)
        , f_ui(new Fill::MainWindow) //Error: Allocation of incomlepete type
    {
    
    }
    
    FillCombo::~FillCombo()
    {
    
    }
    

    Why I have this error, how to do it correctly?



  • I think it is because you have not accually defined a Fill::MainWindow class, you just declare it.
    So the compiler has no way to know how to create a Fill::MainWindow .

    The correct way is:
    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    protected:
        Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H
    

    fillcombo.h

    #ifndef FILLCOMBO_H
    #define FILLCOMBO_H
    
    #include "mainwindow.h"
    
    class FillCombo:public MainWindow
    {
        Q_OBJECT
    public:
        FillCombo(QWidget *parent = nullptr);
        ~FillCombo();
    };
    
    #endif // FILLCOMBO_H
    

    fillcombo.cpp

    #include "fillcombo.h"
    #include "ui_mainwindow.h"
    
    FillCombo::FillCombo(QWidget *parent)
        : MainWindow(parent)
    {
       //just use ui->whatever
    }
    
    FillCombo::~FillCombo()
    {
    }
    


  • @Bonnie I did it your way. Now I have different problem. I wanted to do some operations by this class on ui window.

    So fillcombo.h doesn't change.

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class FillCombo;
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    protected:
        Ui::MainWindow *ui = nullptr;
        FillCombo *f_combo = nullptr;
    };
    #endif // MAINWINDOW_H
    

    fillcombo.cpp

    #include "fillcombo.h"
    //#include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    
    FillCombo::FillCombo(QWidget *parent)
        : MainWindow(parent)
    
    {
        ui->setupUi(this);
        ui->comboBox->addItem("t1");
        ui->comboBox->addItem("t2");
        ui->lineEdit->setText("test1");
    }
    
    FillCombo::~FillCombo()
    {
    
    }
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "fillcombo.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
        , f_combo(new FillCombo)
    {
        ui->setupUi(this);
    
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    

    When I debbug it I get SIGSEGV fault. When I try to run it there is "Program has unexpectly finished" - Is there some problem with pointers?



  • @narrator
    I don't quite understand you code.
    If you want to a new class (FillCombo) that inherits MainWindow and you want it to has something different with MainWindow, you can just use my code and do it

    FillCombo::FillCombo(QWidget *parent)
        : MainWindow(parent)
    {
        ui->comboBox->addItem("t1");
        ui->comboBox->addItem("t2");
        ui->lineEdit->setText("test1");
    }
    

    And if you already has a MainWindow widget and you just want do some change on it, you should not use inherit.
    It dose not work like that.



  • @Bonnie
    The point is that, when I run my example with this code:

    FillCombo::FillCombo(QWidget *parent)
        : MainWindow(parent)
    {
        ui->comboBox->addItem("t1");
        ui->comboBox->addItem("t2");
        ui->lineEdit->setText("test1");
    }
    

    It doesn't change content of combo box or line edit. I suppose the I need to create an object of FillCombo class in initialization list of MainWindow, but the I have problem with debugger.

    Regards.



  • @narrator
    No, MainWindow is the parent class, it should not have anything about the child class in it. Otherwise the whole inheriting would be meaningless.
    Do you just expect a window where the combo and the lineedit has content?
    Then in the main.cpp, instead of

        MainWindow mainWindow;
        mainWindow.show();
    

    you should have

        FillCombo mainWindow;
        mainWindow.show();
    

    Sorry, still not quite understand what you want.



  • @Bonnie Thank you for help.
    But is it possible to modify the content od mainwindow from other classes simultanously?
    For example, I can modify widgets from FillCombo, by using:

    FillCombo mainWindow;
        mainWindow.show();
    

    but now I can't modify content of ombobox and line edit from MainWindow, even if I add:

    MainWindow mainWindow2;
        mainWindow2.show();
    

    I'd like to be able modify it from both classes.



  • @narrator
    As I've said above, if you just want to do some change on an already created MainWindow, you should not use inherit to do that.
    It does not work like that.
    You should add some public functions.

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
        void addComboBoxItem(const QString &text);
        void setLineEditText(const QString &text);
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::addComboBoxItem(const QString &text)
    {
        ui->comboBox->addItem(text);
    }
    
    void MainWindow::setLineEditText(const QString &text)
    {
        ui->lineEdit->setText(text);
    }
    
    

    then you could

    
        MainWindow mainWindow;
        mainWindow.show();
    
        mainWindow.addComboBoxItem("t1");
        mainWindow.addComboBoxItem("t2");
        mainWindow.setLineEditText("test1");
    
    

    I really don't understand what means "be able modify it from both classes".


Log in to reply