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

Qt, ui, C++, Form

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.

#ifndef BASEWIDGET_H
#define BASEWIDGET_H

#include <QWidget>

class BaseWidget : public QWidget
{
    Q_OBJECT
public:
    explicit BaseWidget(QWidget *parent = nullptr);

    // Virtual base class method for validation
    virtual void methodFromBaseClass() const;
};

#endif // BASEWIDGET_H

BaseWidget.cpp

#include "BaseWidget.h"

#include <QDebug>

BaseWidget::BaseWidget(QWidget *parent) : QWidget(parent)
{

}

void BaseWidget::methodFromBaseClass() const
{
    // Outputting a message from a method
    qDebug() << "Base Class Method";
}

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

#ifndef FIRSTFORM_H
#define FIRSTFORM_H

// #include <QWidget> It was
#include "BaseWidget.h" // Became

namespace Ui {
class FirstForm;
}

class FirstForm : public BaseWidget // Changed the base class
{
    Q_OBJECT

public:
    explicit FirstForm(QWidget *parent = nullptr);
    ~FirstForm();

    // Overrided base class method
    virtual void methodFromBaseClass() const override;

private:
    Ui::FirstForm *ui;
};

#endif // FIRSTFORM_H

FirstForm.cpp

#include "FirstForm.h"
#include "ui_FirstForm.h"

#include <QDebug>

FirstForm::FirstForm(QWidget *parent) :
    BaseWidget(parent), // Perform the constructor of the base class
    ui(new Ui::FirstForm)
{
    ui->setupUi(this);
    // Connect the button to the virtual method
    connect(ui->pushButton, &QPushButton::clicked, this, &FirstForm::methodFromBaseClass);
}

FirstForm::~FirstForm()
{
    delete ui;
}

// Implementing the Override Method
void FirstForm::methodFromBaseClass() const
{
    BaseWidget::methodFromBaseClass();
    qDebug() << "First Form Method";
}

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

<widget class="QWidget" name="FirstForm">
    ...
</widget>

Became

<widget class="BaseWidget" name="FirstForm">
    ...
</widget>

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

<customwidgets>
 <customwidget>
  <class>BaseWidget</class>
  <extends>QWidget</extends>
  <header>BaseWidget.h</header>
  <container>1</container>
 </customwidget>
</customwidgets>

The result is the following UI file.

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>FirstForm</class>
 <widget class="BaseWidget" name="FirstForm">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QGridLayout" name="gridLayout">
   <item row="0" column="0">
    <widget class="QPushButton" name="pushButton">
     <property name="text">
      <string>First Form Button</string>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <customwidgets>
  <customwidget>
   <class>BaseWidget</class>
   <extends>QWidget</extends>
   <header>BaseWidget.h</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</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

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class FirstForm;
class SecondForm;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
    FirstForm *m_firstForm;
    SecondForm *m_secondForm;
};

#endif // WIDGET_H

Widget.cpp

#include "Widget.h"
#include "ui_Widget.h"

#include "FirstForm.h"
#include "SecondForm.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_firstForm = new FirstForm(this);
    m_secondForm = new SecondForm(this);

    ui->verticalLayout->addWidget(m_firstForm);
    ui->verticalLayout->addWidget(m_secondForm);
}

Widget::~Widget()
{
    delete ui;
}

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.

Base Class Method
First Form Method
Base Class Method
Second Form Method

Download project application

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate
c

```

Comments

Only authorized users can post comments.
Please, Log in or Sign up
Donate

Hello, Dear Users of EVILEG!!!

If the site helped you, then support the development of the site financially, please.

You can do it by following ways:

Thank you, Evgenii Legotckoi

P
Nov. 19, 2019, 2:23 p.m.
Pan

C++ - Test 001. The first program and data types

  • Result:100points,
  • Rating points10
P
Nov. 19, 2019, 2:20 p.m.
Pan

C++ - Test 001. The first program and data types

  • Result:66points,
  • Rating points-1
O
Nov. 18, 2019, 3:54 p.m.
Oksana

C++ - Test 005. Structures and Classes

  • Result:66points,
  • Rating points-1
Last comments
P
Nov. 19, 2019, 2:10 p.m.
Pan

Здравствуйте. Спасибо за статью. Сделал перевод программы. Все работает. Только я делал не динамический, но это пока и не надо. Но с одной проблемой все же столкнулся. В прог…
v
Nov. 19, 2019, 11:26 a.m.
vintorez10

Разобрался!!! Надо было не архив качать а exe файл и его уже распаковывать в нужную папку)))
v
Nov. 19, 2019, 10:19 a.m.
vintorez10

Ребята а что если папки "Source" в архиве opencv нет? Скачал три варианта библиотеки ни в одном нет этой папки.
c
Nov. 18, 2019, 6:27 a.m.
cyberaxe77

Моих знаний пока явно недостаточно, чтобы писать статьи. Так...небольшие заметки "на полях"))).
Nov. 18, 2019, 6:10 a.m.
Evgenij Legotskoj

Пока что на сайте нет активных пользователей PyQt5, кто бы мог писать статьи по PyQt5, к сожалению. Лично я только для статей пользуюсь этой библиотекой. Но можете стать одним из первых ;) Любой…
Now discuss on the forum
Nov. 19, 2019, 8:10 a.m.
Intruder

Михаил, добрый день. Без разницы в дизайнере создается форма или не в дизайнере. Как вы добавляете в QTabWidget? Нашел видеоурок и по нему все сделал. Все получилось. QtabWidg…
Nov. 19, 2019, 7:22 a.m.
Evgenij Legotskoj

Ну тогда создайте, пожалуйста, потом новую тему на форуме с тем кодом, а то мы с вами в оффтоп ушли, здесь немного не о том было обсуждение.
Nov. 19, 2019, 6:18 a.m.
BlinCT

Спасибо за идею. Сейчас попробою.
Nov. 19, 2019, 2:36 a.m.
BlinCT

Всем привет. Если кто дебажил qml часть подскажиет пожалуйста, какие настрйоки требуются в Qt Creator? Я собирал 5.12.5 из исходников, в Настройкс в debugger у меня выставлен путь к со…
EVILEG
About
Services
© EVILEG 2015-2019
Recommend hosting TIMEWEB