Qt visual interface compilation and calling

        In the previous chapter, we implemented a simple adder, designed the interface through Qt Designer, and then completed the "calculation" function through signals and slots. In this chapter, we will study how the interface designed with Qt Designer is compiled by Qt Creator and called by the main program.

        Let's see what the interface designed with Qt Designer in the previous chapter looks like:

4211c916e05e4666876c414e44d7f02f.png

        As can be seen from this layout diagram, this interface consists of 7 labels, 2 digital input boxes, 1 button, 1 horizontal placeholder, 4 vertical layouts, 2 horizontal layouts and a central control. The following List all controls and their names in the interface:

        The 7 labels are: "simple adder" label_6, "addend 1" label_1, "addend 2" label_2, "result" label_3, "+" label_4, "="label_5, the label for storing the result (with border) resultLabel ;

        2 digital input boxes: addend 1 digital input box add1SpinBox, addend 2 digital input box add2SpinBox;

        1 button: "calculate" button calculatePushButton;

        1 horizontal placeholder: the blue spring-like strip horizontalSpacer on the left side of the calculation button in the figure;

        4 vertical layouters: addend 1 vertical layouter verticalLayout_1, addend 2 vertical layouter verticalLayout_2, result vertical layouter verticalLayout_3, and some forgot, layouter verticalLayout_4 for vertical layout of the entire interface;

        2 horizontal layouters: the horizontal layouter horizontalLayout_1 for the row of input numbers and results, the horizontal layouter horizontalLayout_2 for the row of horizontal placeholders and calculation buttons;

        Central control: the central control centralwidget used to hold all controls in the interface.

        We want to study how Qt Creator compiles these controls into code. Before that, let's take a look at how the Qt C++ application is started and how the window runs. Let's first look at the code in main.cpp where the entry function main() function of the Qt C++ application is located:

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

         The code in main.cpp is very simple, only a few lines. First, it contains two header files, one is the header file "mainwindow.h" of the main window MainWindow class, and the other is the Qt application header file <QApplication>.

        Next is the main() function, the entry function of the Qt C++ program. In the main() function, there are only 4 lines of code. The first line defines an object a of the QApplication class, and passes in the main() function in the constructor. The actual parameter; the second line defines an object w of the main window class MainWindow; the third line executes the show() function of w, which is used to display the main window on the screen; the fourth line main() function returns a .exec(), the function of this code is to execute the QApplication application program, and hand over the control of the program to Qt.

        QApplication is a class of Qt core, we don't need to go into it, we just need to look at the MainWindow class, the following is the code in 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::on_calculatePushButton_clicked()
{
    // 获取加数1的值
    int add1 = ui->add1SpinBox->value();
    // 获取加数2的值
    int add2 = ui->add2SpinBox->value();
    // 计算和
    int result = add1 + add2;
    // 将计算和显示出来
    ui->resultLabel->setText(QString::number(result));
}

        The mainwindow.cpp code contains two header files, one is mainwindow.h, which is the header file of the MainWindow class; the other is ui_mainwindow.h, which is the interface compiled file, and Qt Creator translates the interface into code and stores it in ui_mainwindow. h header file. Let's look at the contents of ui_mainwindow.h:

/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created by: Qt User Interface Compiler version 5.14.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpacerItem>
#include <QtWidgets/QSpinBox>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_MainWindow
{
public:
    QWidget *centralwidget;
    QVBoxLayout *verticalLayout_4;
    QLabel *label_6;
    QHBoxLayout *horizontalLayout_1;
    QVBoxLayout *verticalLayout_1;
    QLabel *label_1;
    QSpinBox *add1SpinBox;
    QLabel *label_4;
    QVBoxLayout *verticalLayout_2;
    QLabel *label_2;
    QSpinBox *add2SpinBox;
    QLabel *label_5;
    QVBoxLayout *verticalLayout_3;
    QLabel *label_3;
    QLabel *resultLabel;
    QHBoxLayout *horizontalLayout_2;
    QSpacerItem *horizontalSpacer;
    QPushButton *calculatePushButton;

    void setupUi(QMainWindow *MainWindow)
    {
        if (MainWindow->objectName().isEmpty())
            MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
        MainWindow->resize(291, 187);
        centralwidget = new QWidget(MainWindow);
        centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
        verticalLayout_4 = new QVBoxLayout(centralwidget);
        verticalLayout_4->setObjectName(QString::fromUtf8("verticalLayout_4"));
        label_6 = new QLabel(centralwidget);
        label_6->setObjectName(QString::fromUtf8("label_6"));
        QFont font;
        font.setPointSize(12);
        font.setBold(true);
        font.setWeight(75);
        label_6->setFont(font);
        label_6->setAlignment(Qt::AlignCenter);

        verticalLayout_4->addWidget(label_6);

        horizontalLayout_1 = new QHBoxLayout();
        horizontalLayout_1->setObjectName(QString::fromUtf8("horizontalLayout_1"));
        verticalLayout_1 = new QVBoxLayout();
        verticalLayout_1->setObjectName(QString::fromUtf8("verticalLayout_1"));
        label_1 = new QLabel(centralwidget);
        label_1->setObjectName(QString::fromUtf8("label_1"));
        label_1->setAlignment(Qt::AlignCenter);

        verticalLayout_1->addWidget(label_1);

        add1SpinBox = new QSpinBox(centralwidget);
        add1SpinBox->setObjectName(QString::fromUtf8("add1SpinBox"));

        verticalLayout_1->addWidget(add1SpinBox);


        horizontalLayout_1->addLayout(verticalLayout_1);

        label_4 = new QLabel(centralwidget);
        label_4->setObjectName(QString::fromUtf8("label_4"));
        QFont font1;
        font1.setPointSize(16);
        label_4->setFont(font1);
        label_4->setAlignment(Qt::AlignCenter);

        horizontalLayout_1->addWidget(label_4);

        verticalLayout_2 = new QVBoxLayout();
        verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2"));
        label_2 = new QLabel(centralwidget);
        label_2->setObjectName(QString::fromUtf8("label_2"));
        label_2->setAlignment(Qt::AlignCenter);

        verticalLayout_2->addWidget(label_2);

        add2SpinBox = new QSpinBox(centralwidget);
        add2SpinBox->setObjectName(QString::fromUtf8("add2SpinBox"));

        verticalLayout_2->addWidget(add2SpinBox);


        horizontalLayout_1->addLayout(verticalLayout_2);

        label_5 = new QLabel(centralwidget);
        label_5->setObjectName(QString::fromUtf8("label_5"));
        label_5->setFont(font1);
        label_5->setAlignment(Qt::AlignCenter);

        horizontalLayout_1->addWidget(label_5);

        verticalLayout_3 = new QVBoxLayout();
        verticalLayout_3->setObjectName(QString::fromUtf8("verticalLayout_3"));
        label_3 = new QLabel(centralwidget);
        label_3->setObjectName(QString::fromUtf8("label_3"));
        label_3->setAlignment(Qt::AlignCenter);

        verticalLayout_3->addWidget(label_3);

        resultLabel = new QLabel(centralwidget);
        resultLabel->setObjectName(QString::fromUtf8("resultLabel"));
        resultLabel->setFrameShape(QFrame::Box);
        resultLabel->setFrameShadow(QFrame::Sunken);
        resultLabel->setLineWidth(1);
        resultLabel->setMidLineWidth(0);
        resultLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
        resultLabel->setMargin(0);
        resultLabel->setOpenExternalLinks(false);

        verticalLayout_3->addWidget(resultLabel);


        horizontalLayout_1->addLayout(verticalLayout_3);

        horizontalLayout_1->setStretch(0, 10);
        horizontalLayout_1->setStretch(2, 10);
        horizontalLayout_1->setStretch(4, 10);

        verticalLayout_4->addLayout(horizontalLayout_1);

        horizontalLayout_2 = new QHBoxLayout();
        horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
        horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

        horizontalLayout_2->addItem(horizontalSpacer);

        calculatePushButton = new QPushButton(centralwidget);
        calculatePushButton->setObjectName(QString::fromUtf8("calculatePushButton"));

        horizontalLayout_2->addWidget(calculatePushButton);


        verticalLayout_4->addLayout(horizontalLayout_2);

        MainWindow->setCentralWidget(centralwidget);

        retranslateUi(MainWindow);

        QMetaObject::connectSlotsByName(MainWindow);
    } // setupUi

    void retranslateUi(QMainWindow *MainWindow)
    {
        MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MainWindow", nullptr));
        label_6->setText(QCoreApplication::translate("MainWindow", "\347\256\200\346\230\223\345\212\240\346\263\225\345\231\250", nullptr));
        label_1->setText(QCoreApplication::translate("MainWindow", "\345\212\240\346\225\2601", nullptr));
        label_4->setText(QCoreApplication::translate("MainWindow", "+", nullptr));
        label_2->setText(QCoreApplication::translate("MainWindow", "\345\212\240\346\225\2602", nullptr));
        label_5->setText(QCoreApplication::translate("MainWindow", "=", nullptr));
        label_3->setText(QCoreApplication::translate("MainWindow", "\347\273\223\346\236\234", nullptr));
        resultLabel->setText(QCoreApplication::translate("MainWindow", "0", nullptr));
        calculatePushButton->setText(QCoreApplication::translate("MainWindow", "\350\256\241\347\256\227", nullptr));
    } // retranslateUi

};

namespace Ui {
    class MainWindow: public Ui_MainWindow {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_MAINWINDOW_H

        We see the comment at the top of this file, which means: This file is generated by the interface file 'mainwindow.ui', created by Qt user interface compilation version 5.14.2. warn! All changes to this file will be lost when compiling the interface file.

        That is to say, this file is automatically generated by Qt according to the interface, and the user does not need to change it. Let's take a look at the codes in this file: first, the header of the file contains the header files used, and then defines a class Ui_MainWindow. In this class, some public pointer variables are defined. These variables are the interfaces listed above. The name of the control is the set objectName, and then a public function void setupUi(QMainWindow *MainWindow) is defined. In this function, each control object is instantiated, and the properties of each control and the layout of the interface are set. Is it very similar to our manual Lu's code, but because it is automatically generated by the machine, it seems a bit mechanized, but the effect is the same. Pay attention to one of the statements, which is QMetaObject::connectSlotsByName(MainWindow); the function of this statement is to search for all the controls on the MainWindow interface, associate the signal with the slot function matching the signal and the slot, and use it as the void class name ::on_control_name_signal(); The declaration of this slot function enables the signal of the control to be directly associated with such a slot function.

        In addition to the setupUi function, this class also defines a void retranslateUi(QMainWindow *MainWindow) function. This function is used to set the text content attributes of each component of the interface, such as the title of the window, the text of the label, and the text of the button. The content of the text setting is independent as a function, which will be used when designing a multilingual interface.

        At the end of the function, there is the following statement:

namespace Ui {
    class MainWindow: public Ui_MainWindow {};

These statements define the namespace Ui, and define a class MainWindow that inherits Ui_MainWindow. The meaning of this operation will be discussed later.

        Next, let's look at the code in 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();

private:
    Ui::MainWindow *ui;

private slots:
    void on_calculatePushButton_clicked();
};
#endif // MAINWINDOW_H

        In the mainwindow.h file, the <QMainWindow> header file is first included, and then the namespace namespace Ui { class MainWindow; } is declared. Note that the class MainWindow here is the class in the namespace Ui, the Ui namespace and the MainWindow under it It is defined in the ui_mainwindow.h file, and it is only used here to explicitly declare that it is used in the MainWindow class defined in the mainwindow.h file.

        Let's see what the MainWindow class defined in the mainwindow.h file contains. First, this class inherits from QMainWindow. There is a Q_OBJECT macro definition inside the class. Before declaring signals and slots, you must use the macro definition Q_OBJECT. The constructor and destructor are declared in the class, which are public functions. Then a private pointer variable Ui::MainWindow *ui is defined; we carefully analyze this pointer variable, the type of the pointer variable ui is Ui::MainWindow, which is the MainWindow defined in the ui_mainwindow.h file, so this ui pointer variable can Access to all public variables and functions inside MainWindow defined in the ui_mainwindow.h file, that is, all controls on the interface can be accessed through the pointer variable ui.

        The class that implements interface functions in the ui_mainwindow.h file is Ui_MainWindow, and then define a class MainWindow to inherit Ui_MainWindow and define it in the namespace Ui, so that Ui::MainWindow has the same name as the class MainWindow in the mainwindow.h file, but it is distinguished by namespace . Therefore, the Ui::MainWindow class of the interface and the MainWindow class defined in the file mainwindow. Just use the ui pointer to access the controls of the interface. Do you feel that the design of Qt is very ingenious and smooth!

        The public slot function void on_calculatePushButton_clicked() declared in the last part of the MainWindow class in mainwindow.h; this is the slot function of the click signal clicked link of the "calculate" button calculatePushButton, the reason why this slot function can be triggered by the click signal of the "calculate" button , entirely because of the function of a statement QMetaObject::connectSlotsByName(MainWindow) in the Ui_MainWindow class in the ui_mainwindow.h file.

        After talking about mainwindow.h, let's go back and look at the contents of mainwindow.cpp. In the constructor of MainWindow, the ui pointer variable is instantiated by using new Ui::MainWindow to open up space, and ui is no longer a null pointer. In the constructor, use ui->setupUi(this); to initialize the interface. In the destructor of MainWindow, release the ui pointer. The slot function void on_calculatePushButton_clicked() is defined in mainwindow.cpp to realize the simple adder calculation function.

        At this point, we have finished the code framework of the simple adder. Are you clear, friends? If not, you can understand it after reading the code a few times.

 

Guess you like

Origin blog.csdn.net/weixin_47488212/article/details/130210198