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 itFillCombo::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 ofMainWindow 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".