Qt入门之UI文件设计与运行机制

Qt入门之UI文件设计与运行机制

QMainWindow 是主窗口类,主窗口具有主菜单栏,工具栏和状态栏,类似于一般的应用程序的窗口

QWidget是所有具体可视界面类的基类,选择QWidget 创建的界面对各种界面组件都可以支持

QDialog是对话框类,可建立一个基于对话框的界面

项目文件组成

1.项目组织文件samp2_1.pro,存储项目设置的文件

#表示加入了 core gui模块。 core gui是Qt用于GUI设计的类库模板,如果创建的是控制台(console)应用程序,就不需要加入 core gui
#Qt类库以模块的形式组织各种功能的类,根据项目涉及的需求,在项目中添加适当的类库模块支持,例如,如果项目中使用到了设计数据库操作的类就需要用到sql的模块,在pro文件中需要增加如下一行
#QT       +=sql
QT       += core gui

#这是个条件执行语句,表示当QT的版本大于4时,才加入widgets模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

#表示生产的目标可执行文件的名称,即编译后的可执行文件是samp2_1.exe
TARGET = samp2_1
#表示项目使用的模板是app,是一般的应用程序
TEMPLATE = app

CONFIG += c++11

#SOURCES 、HEADERS 、FORMS 记录了项目中包含的源程序文件、头文件和窗体文件(.ui文件)的名称。这些文件列表是Qt Creator自动添加到项目管理文件里面的,用户不需要手动修改。当从项目添加或删除一个文件时,项目管理文件的条目会自动修改
SOURCES += \
        main.cpp \
        widget.cpp

HEADERS += \
        widget.h

FORMS += \
        widget.ui

2.主函数文件main.cpp

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

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);   //Qt的标准应用程序类
    Widget w;    //定义并创建窗口
    w.show();    //显示窗口

    return a.exec();    //启动应用程序的执行,开始应用程序的消息循环和事件处理
}

3.窗体相关文件

将项目编译,编译后在项目目录下会自动生成一个ui_widget.h文件(在编译后的文件夹里),这样,对于一个窗体,就有4个文件了 :

widget.h   定义窗体类的头文件,定义了类Widget

widget.cpp   Widget类的功能实现源程序文件

widget.ui     窗体界面文件,

ui_widget.h  编译后,根据窗体上的组件及属性、信号与槽的关联等自动生成的一个类的定义文件,类的名称是Ui_Widget

下面分析各个文件的内容及其功能,以及他们是如何联系到一起工作,实现界面的创建与显示的。

3.1 widget.h文件

widget.h文件是窗体类的头文件。在创建项目时,选择窗体基类的QWidget,在widget.h中定义一个继承自QWidget的类的Widget:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;       //声明了一个名称为 Ui 的命名空间,包含一个类Widget。但这个Widget类并不是本文件里定义的类Widget,而是ui_widget.h文件中定义的类,用于描述组件的。这个声明相当与一个外部声明(具体看完ui_widget.h文件才能搞明白)
}

class Widget : public QWidget    //本实例窗口类Widget的定义
{
    Q_OBJECT    //使用Qt的信号与槽机制都必须加入的宏

public:
    explicit Widget(QWidget *parent = nullptr);    //构造函数
    ~Widget();    //析构函数

private:
    Ui::Widget *ui;     //这个指针是用前面namespace Ui里的Widget类定义的,所以指针ui指向可视化设计的界面,要访问界面上的组件,都需要通过这个ui指针
};

#endif // WIDGET_H

3.2 widget.cpp文件

widget.cpp文件是类Widget的实现代码:

#include "widget.h"
#include "ui_widget.h"      //Qt编译生产的与UI文件widget.ui对应的类定义文件

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)      //执行父类QWidget的构造函数,创建一个Ui::Widget类的对象ui,这个ui就是Widget的private部分定义的指针变量ui。可参考:https://blog.csdn.net/GouplovXim1314/article/details/104349423
{
    ui->setupUi(this);      //这个函数实现了窗口的生产与各种属性的设置、信号与槽的关联
}

Widget::~Widget()
{
    delete ui;    //析构函数
}

所以,在 ui_widget.h 文件里有一个 namespace 名称为 Ui,里面有一个类 Widget 类用于描述可视化的窗体,且与widget.h里定义的类同名。在Widget类里访问 Ui::Widget类的成员变量或函数需要通过Widget类里的 ui 指针,如果构造函数里执行 ui->setupUi(this)函数那样。

3.3 ui_widget.h文件

ui_widget.h文件是在对 widget.ui 文件编译后生成的一个文件,ui_widget.h会出现在编译后的目录下,或与widget.ui同目录(与项目的 shadow build编译设置有关)。

文件ui_widget.h并不会出现在 Qt Creator 的项目文件目录树里,可手动添加

/********************************************************************************
** Form generated from reading UI file 'widget.ui'
**
** Created by: Qt User Interface Compiler version 5.9.7
**
** 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/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QLabel *label;
    QPushButton *btnClose;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName(QStringLiteral("Widget"));
        Widget->resize(400, 300);
        QFont font;
        font.setFamily(QStringLiteral("Aharoni"));
        font.setPointSize(12);
        font.setBold(true);
        font.setWeight(75);
        Widget->setFont(font);
        label = new QLabel(Widget);
        label->setObjectName(QStringLiteral("label"));
        label->setGeometry(QRect(120, 110, 91, 31));
        label->setFont(font);
        btnClose = new QPushButton(Widget);
        btnClose->setObjectName(QStringLiteral("btnClose"));
        btnClose->setGeometry(QRect(240, 210, 75, 23));

        retranslateUi(Widget);
        QObject::connect(btnClose, SIGNAL(clicked()), Widget, SLOT(close()));

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

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QApplication::translate("Widget", "Widget", Q_NULLPTR));
        label->setText(QApplication::translate("Widget", "Hello Word", Q_NULLPTR));
        btnClose->setText(QApplication::translate("Widget", "\345\205\263\351\227\255", Q_NULLPTR));
    } // retranslateUi

};

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

QT_END_NAMESPACE

#endif // UI_WIDGET_H

查看ui_widget.h文件,发现他主要做了一下工作:

(1)定义了一个类Ui_Widget,用于封装可视化界面的设计

(2)自动生成了界面各个组件的类成员变量定义。在 public 部分为界面上每个组件定义了一个指针变量,变量的名称就是设置的objectName。比如,在窗体上放置一个QLabel 和 一个QPushButton并命名后,会自动生成定义是:QLabel *LabDemo; QPushButton *btnClose;

(3)定义了setupUi()函数,这个函数用来创建各个界面组件,并设置其位置、大小、文字内容、字体等属性,设置信号与槽的关联。

  • setupUi()函数体的第一部分是根据可视化设计界面内容,用C++代码 创建界面上的个组件,并设置其属性。
  • 接下来,setupUi()调用了函数 retranslateUi(Widget),用来设置界面各组件的文字内容属性,如标签的文字、按键的文字、窗体的标题等。将界面上的文字内容独立出来作为一个函数retranslateUi(),在设计多语言界面时会用到这个函数。
  • setupUi()函数的第三部分是设置信号与槽的关联,本文件中有以下两行:

    QObject::connect(btnClose, SIGNAL(clicked()), Widget, SLOT(close()));

    QMetaObject::connectSlotsByName(Widget);

    第一行是调用 connect() 函数,将在UI设计器里设置的信号与槽的关联转换为语句。

    第二行是设置槽函数的关联方式,用于将UI设计器自动生产的组件信号的槽函数与组件信号关联

    所以:在Widget 的构造函数里调用 ui->setupUi(this),就实现了窗体上组件的创建、属性设置、信号与槽的关联

  • 定义 namespace Ui,并定义一个从 Ui_Widget 继承的类 Widget

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章