Evgenii Legotckoi
July 3, 2018, 12:24 a.m.

Qt/C++ - Tutorial 081. How to make a base class for widgets using ui form files

In some cases, you might need to create widget form classes that have a custom base class. That is, the form class of the widget will be inherited from your class, and not directly from QWidget , QDialog , or QMainWindow .

Naturally, for this, your custom class must be inherited from one of these three classes. But at the same time you will have your own base class for any specific functionality, no matter what. Do not make Holivar about how convenient or uncomfortable it is to use Qt Designer or it's better to write everything manually in the code. I know that some programmers do not accept the use of Qt Designer. But let us dwell on the fact that for me it is convenient, as for some other programmers.

Let's create two classes of FirstForm and SecondForm forms that will be inherited from the BaseWidget widget, which in turn is inherited from QWidget .

The appearance of the application window will be as follows.


Project structure

The Widget form class in this case is the application's base window, into which we will put the FirstForm and SecondForm widgets.

BaseWidget

In the BaseWidget base class, we define a virtual method that we will redefine in the inherited widgets. This will show us that this inheritance does work.

BaseWidget.h

Header file of the class.

  1. #ifndef BASEWIDGET_H
  2. #define BASEWIDGET_H
  3.  
  4. #include <QWidget>
  5.  
  6. class BaseWidget : public QWidget
  7. {
  8. Q_OBJECT
  9. public:
  10. explicit BaseWidget(QWidget *parent = nullptr);
  11.  
  12. // Virtual base class method for validation
  13. virtual void methodFromBaseClass() const;
  14. };
  15.  
  16. #endif // BASEWIDGET_H

BaseWidget.cpp

  1. #include "BaseWidget.h"
  2.  
  3. #include <QDebug>
  4.  
  5. BaseWidget::BaseWidget(QWidget *parent) : QWidget(parent)
  6. {
  7.  
  8. }
  9.  
  10. void BaseWidget::methodFromBaseClass() const
  11. {
  12. // Outputting a message from a method
  13. qDebug() << "Base Class Method";
  14. }

FirstForm

Both form classes will need to be generated using the class creation wizard. In this case, we choose QWidget as the base class.

After creating the class, you will need to fix some of the code, as well as fix the ui file.

After we create a new class, add a button to the form of this class.

FirstForm.h

  1. #ifndef FIRSTFORM_H
  2. #define FIRSTFORM_H
  3.  
  4. // #include <QWidget> It was
  5. #include "BaseWidget.h" // Became
  6.  
  7. namespace Ui {
  8. class FirstForm;
  9. }
  10.  
  11. class FirstForm : public BaseWidget // Changed the base class
  12. {
  13. Q_OBJECT
  14.  
  15. public:
  16. explicit FirstForm(QWidget *parent = nullptr);
  17. ~FirstForm();
  18.  
  19. // Overrided base class method
  20. virtual void methodFromBaseClass() const override;
  21.  
  22. private:
  23. Ui::FirstForm *ui;
  24. };
  25.  
  26. #endif // FIRSTFORM_H

FirstForm.cpp

  1. #include "FirstForm.h"
  2. #include "ui_FirstForm.h"
  3.  
  4. #include <QDebug>
  5.  
  6. FirstForm::FirstForm(QWidget *parent) :
  7. BaseWidget(parent), // Perform the constructor of the base class
  8. ui(new Ui::FirstForm)
  9. {
  10. ui->setupUi(this);
  11. // Connect the button to the virtual method
  12. connect(ui->pushButton, &QPushButton::clicked, this, &FirstForm::methodFromBaseClass);
  13. }
  14.  
  15. FirstForm::~FirstForm()
  16. {
  17. delete ui;
  18. }
  19.  
  20. // Implementing the Override Method
  21. void FirstForm::methodFromBaseClass() const
  22. {
  23. BaseWidget::methodFromBaseClass();
  24. qDebug() << "First Form Method";
  25. }

FirstForm.ui

And here is the most interesting. To force the project to compile, you need to write a base class and information about inheritance in the UI file.

First, write the base class into the widget of the form class.

It was

  1. <widget class="QWidget" name="FirstForm">
  2. ...
  3. </widget>

Became

  1. <widget class="BaseWidget" name="FirstForm">
  2. ...
  3. </widget>

Secondly, write information about custom widgets with an indication of inheritance and the header file.

  1. <customwidgets>
  2. <customwidget>
  3. <class>BaseWidget</class>
  4. <extends>QWidget</extends>
  5. <header>BaseWidget.h</header>
  6. <container>1</container>
  7. </customwidget>
  8. </customwidgets>

The result is the following UI file.

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <ui version="4.0">
  3. <class>FirstForm</class>
  4. <widget class="BaseWidget" name="FirstForm">
  5. <property name="geometry">
  6. <rect>
  7. <x>0</x>
  8. <y>0</y>
  9. <width>400</width>
  10. <height>300</height>
  11. </rect>
  12. </property>
  13. <property name="windowTitle">
  14. <string>Form</string>
  15. </property>
  16. <layout class="QGridLayout" name="gridLayout">
  17. <item row="0" column="0">
  18. <widget class="QPushButton" name="pushButton">
  19. <property name="text">
  20. <string>First Form Button</string>
  21. </property>
  22. </widget>
  23. </item>
  24. </layout>
  25. </widget>
  26. <customwidgets>
  27. <customwidget>
  28. <class>BaseWidget</class>
  29. <extends>QWidget</extends>
  30. <header>BaseWidget.h</header>
  31. <container>1</container>
  32. </customwidget>
  33. </customwidgets>
  34. <resources/>
  35. <connections/>
  36. </ui>

SecondForm

Here is a similar program code.

Widget

Next, you need to add instances of these classes to the main application window. For clarity, we'll do it manually.

Widget.h

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3.  
  4. #include <QWidget>
  5.  
  6. class FirstForm;
  7. class SecondForm;
  8.  
  9. namespace Ui {
  10. class Widget;
  11. }
  12.  
  13. class Widget : public QWidget
  14. {
  15. Q_OBJECT
  16.  
  17. public:
  18. explicit Widget(QWidget *parent = nullptr);
  19. ~Widget();
  20.  
  21. private:
  22. Ui::Widget *ui;
  23. FirstForm *m_firstForm;
  24. SecondForm *m_secondForm;
  25. };
  26.  
  27. #endif // WIDGET_H

Widget.cpp

  1. #include "Widget.h"
  2. #include "ui_Widget.h"
  3.  
  4. #include "FirstForm.h"
  5. #include "SecondForm.h"
  6.  
  7. Widget::Widget(QWidget *parent) :
  8. QWidget(parent),
  9. ui(new Ui::Widget)
  10. {
  11. ui->setupUi(this);
  12. m_firstForm = new FirstForm(this);
  13. m_secondForm = new SecondForm(this);
  14.  
  15. ui->verticalLayout->addWidget(m_firstForm);
  16. ui->verticalLayout->addWidget(m_secondForm);
  17. }
  18.  
  19. Widget::~Widget()
  20. {
  21. delete ui;
  22. }

Result

When compiling the application, we get a window, as shown at the beginning of the article. And in the console when you press the buttons, we get the following output.

  1. Base Class Method
  2. First Form Method
  3. Base Class Method
  4. Second Form Method

Download project application

Do you like it? Share on social networks!

c
  • Aug. 31, 2019, 3:13 p.m.
  • (edited)

```

Comments

Only authorized users can post comments.
Please, Log in or Sign up
  • Last comments
  • Evgenii Legotckoi
    March 9, 2025, 9:02 p.m.
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    March 9, 2025, 4:14 p.m.
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
  • ИМ
    Nov. 22, 2024, 9:51 p.m.
    Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
  • Evgenii Legotckoi
    Oct. 31, 2024, 11:37 p.m.
    Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
  • A
    Oct. 19, 2024, 5:19 p.m.
    Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html