Evgenii Legotckoi
Evgenii LegotckoiJuly 2, 2018, 2:24 p.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.

#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.

Do you like it? Share on social networks!

c
  • Aug. 31, 2019, 5:13 a.m.
  • (edited)

```

Comments

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

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
m

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:80points,
  • Rating points4
m

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:20points,
  • Rating points-10
Last comments
ИМ
Игорь МаксимовNov. 22, 2024, 10:51 p.m.
Django - Tutorial 017. Customize the login page to Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii LegotckoiNov. 1, 2024, 12:37 a.m.
Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEOct. 19, 2024, 6:19 p.m.
Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовOct. 5, 2024, 5:51 p.m.
Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5July 5, 2024, 9:02 p.m.
QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Now discuss on the forum
Evgenii Legotckoi
Evgenii LegotckoiJune 25, 2024, 1:11 a.m.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey1Nov. 15, 2024, 5:04 p.m.
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProjectJune 4, 2022, 1:49 p.m.
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9AnonimOct. 25, 2024, 7:10 p.m.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Follow us in social networks