Qt界面文件原理

 

目录

Qt的UI文件如何与窗口类关联?

一、widget项目的基本组成

二、ui_widget.h中的内容。

三、widget.h 、widget.cpp 与 ui_widget.h之间的关联

总结


Qt的UI文件如何与窗口类关联?

一、widget项目的基本组成

当我们用Qt creater新建一个widget项目时,会有五个文件如图:

  • UI.pro
  • widget.h
  • main.cpp
  • widget.cpp
  • widget.ui

UI.pro文件和main.cpp文件与本文主要内容关系不大,所以不会涉及这两个文件相关的内容,这两个文件的内容之后在进行阐述。

widget.h文件内容:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

widget.cpp代码如下:

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

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

widget.ui点开则是设计师界面:

那么这三个文件是怎么关联起来的呢?

当你初次构建该项目的时候,会生成一个 文件,内容如下:

该文件中包含一个 ui_widget.h 的文件,查看 Qt creator编译输出栏可以看到如下信息:

D:\Qt\Qt5.12.4\5.12.4\mingw73_64\bin\uic.exe ..\UI\widget.ui -o ui_widget.h

可以看到 Qt 通过 uic.exe 工具将 widget.ui文件生成了目标文件 ui_widget.h,也就是说 设计师界面的所有内容最终被包含在ui_widget.h这个文件中;

二、ui_widget.h中的内容。

接下来打开 ui_widget.h 文件看看其中的内容:

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

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName(QString::fromUtf8("Widget"));
        Widget->resize(400, 300);

        retranslateUi(Widget);

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

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QApplication::translate("Widget", "Widget", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

ui_widget.h中有注释、Ui_Widget类的定义、Ui名称空间的定义。

1.其中最上面三行注释翻译如下:

  1. 通过读取UI文件'widget.ui'生成;
  2. 创建者:Qt User Interface Compiler版本5.12.4;
  3. 警告! 重新编译UI文件时,此文件中所做的所有更改都将丢失!

通过以上注释可以得知:只要我们修改了 widget.ui  文件,然后重新编译,该文件就会重新生成。

2.该文件中定义了一个类 Ui_Widget类,类方法中的对象对应的是 设计师界面的控件!

其中:QMetaObject::connectSlotsByName(Widget);

 递归搜索给定对象的所有子对象,并将匹配信号从它们连接到以下格式的对象槽函数:

   void on_ <对象名称> _ <信号名称>(<信号参数>);

假设我们的对象有一个QPushButton类型的子对象,其对象名称为button1。 捕获按钮的clicked()信号的槽函数为:

   void on_button1_clicked();

3.声明了 名为 Ui 的名称空间,该名称空间中定义了 一个类 Widget,并继承了 Ui_Widget这个类!

三、widget.h 、widget.cpp 与 ui_widget.h之间的关联

现在回看 widget.h 文件中代码:

namespace Ui {
class Widget;
}

在命名空间中进行了 类的前置声明,而该类则是在ui_widget.h中进行定义;

private:
    Ui::Widget *ui;

定义了一个Ui::Widget类的指针。

该Ui::Widget类就是 ui_widget.h中定义的,因为ui_widget.h中 的内容 是设计师界面内容的映射, 所以 指针 ui 在实例化之后可以控制、操作界面。

widget.cpp中:

#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

包含了ui_widget.h 文件,并 new 了一个 Ui::Widget的实例,赋给Ui。使用 ui->setupUi(this),这个函数的作用是对界面进行初始化,它按照我们在Qt设计器里设计的样子把窗体画出来,把我们在Qt设计器里面定义的信号和槽建立起来。

总结

编译过程中窗口界面 widget.ui 生成 ui_widget.h文件,在该文件的setupUi函数中,将所有的子控件全部画出来,然后将子控件的信号与槽进行连接,实现了界面文件的绘制。

整个实现过程中,又使用了一种设计机制:pImpl ,实现了ui文件更新,只需编译相应的ui_widget.h文件,而不需要重新编译其他任何文件。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值