Qt中的UI文件介绍

UI文件是什么?

. u i .ui .ui通常是指Qt设计师设计出来的界面文件的后缀,它本质上是一个标准XML格式的文本文件,需要通过 u i c uic uic工具将其转换为项目中可用的 u i _ ∗ . h ui\_*.h ui_.h头文件

使用时ui是一个指向这个界面类的指针:
u i − > ui-> ui>一般就是用来访问这个界面类里面的控件

例如你的ui文件里有一个叫okButton的QPushButton的组件,你就可以通过ui->okButton来访问这个按钮

UI文件的简单实现

我们新建一个Qt项目,它会自动生成一个h头文件、一个ui文件、一个cpp源文件和一个main程序入口,并生成一些默认实现(成员变量的使用方式)
在这里插入图片描述

我们编译工程之后,ui文件就会被编译成ui_*.h文件

ui_helloworld.h文件代码:

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

QT_BEGIN_NAMESPACE

class Ui_MainWindow
{
public:
    QWidget *centralWidget;
    QPushButton *OKButton;
    QMenuBar *menuBar;
    QToolBar *mainToolBar;
    QStatusBar *statusBar;

    void setupUi(QMainWindow *MainWindow)
    {
        if (MainWindow->objectName().isEmpty())
            MainWindow->setObjectName(QStringLiteral("MainWindow"));
        MainWindow->resize(400, 300);
        centralWidget = new QWidget(MainWindow);
        centralWidget->setObjectName(QStringLiteral("centralWidget"));
        OKButton = new QPushButton(centralWidget);
        OKButton->setObjectName(QStringLiteral("OKButton"));
        OKButton->setGeometry(QRect(200, 190, 93, 28));
        MainWindow->setCentralWidget(centralWidget);
        menuBar = new QMenuBar(MainWindow);
        menuBar->setObjectName(QStringLiteral("menuBar"));
        menuBar->setGeometry(QRect(0, 0, 400, 26));
        MainWindow->setMenuBar(menuBar);
        mainToolBar = new QToolBar(MainWindow);
        mainToolBar->setObjectName(QStringLiteral("mainToolBar"));
        MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
        statusBar = new QStatusBar(MainWindow);
        statusBar->setObjectName(QStringLiteral("statusBar"));
        MainWindow->setStatusBar(statusBar);

        retranslateUi(MainWindow);

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

    void retranslateUi(QMainWindow *MainWindow)
    {
        MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", Q_NULLPTR));
        OKButton->setText(QApplication::translate("MainWindow", "OK", Q_NULLPTR));
    } // retranslateUi

};

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

QT_END_NAMESPACE

#endif // UI_MAINWINDOW_H

  • 代码开头的注释提醒开发者不要手动修改该头文件,因为 uic 工具下次自动生成 .h 文件时,会把旧的代码全清掉,然后生成新的代码内容。

  • QT_BEGIN_NAMESPACE 和 QT_END_NAMESPACE 这两个宏标示中间的代码是包含在名字空间里的,表示中间的代码是被namespace包裹的。

  • 第一个类是全局范围定义的 Ui_MainWindow 类,里面首先定义了一个 label 指针,注意这个指针名称就是之前设计师里显示的 objectName。

  • 接着定义了一个 s e t u p U i setupUi setupUi 函数,它是最关键的生成图形界面的函数,它接收一个 Q M a i n W i n d o w QMainWindow QMainWindow 对象的指针,然后为这个 Q M a i n W i n d o w QMainWindow QMainWindow 对象设置窗口界面和控件。

  • 还有一个 retranslateUi 函数,是专门用于支持多国语言翻译的,主窗口和标签控件的字符串都在这重新翻译一下,如果有多国语言支持的翻译文件,界面的多国语言显示就通过该函数实现。

      这两个函数细节就不讲解了,以后还会遇到,而且它们都是 uic 自动生成的,不需要我们手动编写或修改,不用太担心细节,学会用这个头文件就可以了。
    
  • 接下来定义了一个叫 Ui 的名字空间,空间里定义了一个类 MainWindow ,简单地从 Ui_mainwindow 类继承一下,并没有添加额外的代码。使用 Ui 名字空间的好处就是避免名称冲突,所以正常都不会直接使用 Ui_Mainwindow 类,而是用名字空间里的 Ui::Mainwindow 类

  • 需要注意的是 ui_hello.h 头文件里没有 Q_OBJECT 宏,它里面定义的类也没有从任何窗口或控件类继承。无论是 U i m a i n w i n d o w Ui_mainwindow Uimainwindow 类还是 U i : : m a i n w i n d o w Ui::mainwindow Ui::mainwindow 类,它们都不是窗口类!
    准确地说 它们通过 setupUi 函数,辅助该函数参数里的窗口对象(QMainWindow *MainWindow)构建图形界面,它们帮助别的窗口类对象构建图形界面,仅此而已当然,在 setupUi 函数里新建的控件指针,如 label,是 Ui_mainwindow 或Ui::mainwindow 类里的成员变量,代码里需要通过这个类的成员变量来操控相应的控件。

如果要在项目里面使用 ui 文件(其实是 ui_*.h),通常有三种方式:直接使用方式多重继承使用方式成员变量使用方式
,使用 Q t C r e a t o r Qt Creator QtCreator 自动生成的代码就是成员变量使用方式。

成员变量使用方式(自动生成的代码)

我们使用Qt Creator新建项目就会自动生成代码,它使用的就是成员变量使用方式。
我们先看他的主入口
main.cpp代码:

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

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);//定义一个 Qt 应用程序对象,它的构造函数接收和 main 函数一样的参数,是 Qt 图形界面程序的入口
    MainWindow w;//定义一个主窗口类变量
    w.show();//展示这个主窗口
    return a.exec();//返回时会进入 Qt 应用程序的事件循环函数等待用户操作和系统的消息然后进行处理
}

说明:常见的c/c++语言main函数中都是直接return 0 的,程序直接退出。
但图形程序通常需要与用户交互,不会自动关闭,而是一直等待用户操作。如果用户点击窗口的关闭按钮, 程序才会结束并返回一个值,默认是 0 。
qt中main函数开始就只是进行一个初始化工作,然后将控制权交给qt,接下来所有事件的处理就只剩下qt的事件循环处理。

看到了他是调用的mainwindow这个类,那我们再深入到这个类中看看是什么?

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);//提供一个构造方法
    ~MainWindow();

private:
    Ui::MainWindow *ui;//将ui类作为私有成员
};

#endif // MAINWINDOW_H

mainwindow.cpp文件代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);//构造函数就是直接调用的setupUi函数
}

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

通过头文件直接使用

如果我们不适用mainwindow这个类,而是直接使用ui文件呢?
答案当然是可以的,mainwindow这个类相当于将ui_.h文件进行的二次封装而已,我们可以直接调用setupUi函数来创建窗体。
直接使用.ui文件其实是使用的ui_
.h文件,编译之后就有了,我们调用它的setupUi函数就可以设置窗体然后显示了;
我们定义一个main.cpp,做为程序主入口

代码:

#include <QApplication>
#include "ui_mainwindow.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);//定义一个Qt应用程序对象
    QMainWindow *w = new QMainWindow();  //新建一个主窗口对象
    Ui::Mainwindow createUi;  //createUi并不是一个真正的窗口对象,相当于我们上面的那个私有成员Ui::MainWindow *ui
    createUi.setupUi(w);  //createUi是创建GUI的工具,将w这个主窗口作为参数传进去
    w->show();  //展示窗口
    return a.exec();
}

这种实现方式其实就是将mainwindow类要实现的任务放到了main主函数中去做,不要使用这种直接调用的方式,没有可扩展性,二次封装将功能分离才是王道。

多重继承法使用.ui文件

上面如果直接使用ui文件的话有一个很大的弊端,对象比较简单,如果要丰富一下主界面的窗口类(例如写两个窗口),就要使用继承的方式

C++ 如果要同时使用两个类的代码,有两种方式:

  • 一种是多重继承的方式,同时用 QMainwindow 和 Ui::Mainwindow 类作为基类;
  • 还有一种是使用成员变量,将 Ui::Mainwindow 类的对象作为 QMainwindow 派生类的成员变量,这种也叫单一继承方式,它的基类只有 QMainwindow。(就是我讲的第一种使用方式)

hellowUi.h文件(继承第一个文件的主窗口的代码和QMainwindow)

#include <QMainwindow>
#include "ui_Mainwindow.h"
class HelloUi : public QMainwindow, public Ui::Mainwindow
{
    Q_OBJECT
public:
    explicit HelloUi(QWidget *parent = 0);
    ~HelloUi();
protected:
    void AdjustLabel();
};
#include "hellowUi.h"
HelloUi::HelloUi(QMainwindow *parent) : QMainwindow(parent)
{
    setupUi(this);  //必须先调用setupUi 函数
    //TODO:
    AdjustLabel();
}
HelloUIWidget::~HelloUIWidget()
{
    //无需手动删除 Label 组件和 widget 组件,它们会被 Qt 自动删除
}
void HelloUIWidget::AdjustLabel()
{
    label->setText("AlbertOS");
}

main.cpp代码:

#include <QtWidgets/QApplication>
#include "hellouiwidget.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    HelloUi *w = new HelloUi();
    w->show();
    return a.exec();
}

编译过程:

  1. 打开 Qt 命令行工具,进入QtDemo 文件夹
  2. 用 uic 生成 ui_hello.h:uic hello.ui -o ui_hello.h
  3. 用 moc 生成元对象系统代码:moc hellouiwidget.h -o moc_hellouiwidget.cpp
  4. 生成可执行程序:g++ moc_hellouiwidget.cpp hellouiwidget.cpp main.cpp -std=c++0x -I"D:\Qt\5.9\mingw53_32\include" -L"D:\Qt\5.9\mingw53_32\lib" -lQt5Core -lQt5Gui -lQt5Widgets -o main
  5. 输入main.exe命令运行生成的程序。

上面讲的是编译链接的全过程,初学的时候就应该了解这些细节知识,如果将来遇上编译或者链接时的错误,就可以很快的找到问题出在哪里;
如果不了这些过程,可能编译的时候少一个ui_.h或者moc_.cpp都不知道是哪错了。

平常我们用的生成方法就是使用qmake工具一键生成,界面下就是那个小锤锤
在这里插入图片描述
还可以调整使用不同的编译环境和编译配置,qmake 把许多 uic、moc、g++ 编译链接过程的命令都自动生成了,全放在 Makefile 脚本里,用起来就特别省事。qmake 创建的各种自动生成命令要比我们自己之前编的命令更为科学合理,感兴趣的读者可以记录一下 mingw32-make 命令执行时命令行里出现的各种生成命令,这些命令都类似于以后的 QtCreator 集成开发环境里面生成程序用的命令。

一些具体的UI组件介绍

在现在的集成开发环境下,QtUI设计师也提供了很多常用的Qt组件
在这里插入图片描述
分别为布局方式、空间弹簧、按钮、项目视图(模型控制)、项目窗口部件(项目控制)、容器、输入框、显示窗口部件

每个组件展开详细描述可就太多了,每个控件都有各自的属性和使用技巧,大家在学的过程中可以慢慢了解和体会,找不到的也可以看看他的help帮助文档。

这些控件对于有前端基础的人来说肯定不难,连取名都很相似,Qt组件库没有html版本的不好演示;
大家可以看element组件库的演示,如果效果对的就在Qt中找名字就好,连组件的Api的取名都差不多。

  • 11
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Qt怎么用Ui文件 第一步, 制作ui文件。 首先应该用Qt Designer绘制一个自己的界面,并存为myform.ui(这里的myform可以用自己喜欢的名字代替)。 在制作自己的界面文件时要注意以下几个要点: 1、要记住ui文件的名字,因为uic生成的代码会存在ui_myform.h里 2、要记住主窗体的object name, 因为ui文件提供的类名将以这个form的名字来命名 3、要特别注意你的form选择的基类要和你代码的窗体类兼容 4、要记得给每个后面需要访问到的控件起一个有意义并且好记的object name, 因为ui文件提供的控件将以这些object name来命名 清楚了以上几点,在代码使用你的ui文件就会变得非常简单。 第二步,将ui文件加入工程 这一步最简单,只需要修改pro文件,加入FORMS+=myform.ui qmake -project命令也可以识别后缀名为ui文件,并将之加入工程。 第三步,在代码引用ui文件 官方介绍的使用ui文件的方法有三种,一个是直接引用,二是单继承,三是多继承。 第一种方法其实很不实用,大家去看一下文档的例子就可以了;第二种和第三种没有本质的差别,可以并作一类,这里做重点介绍ui文件最终会被翻译成标准的C++代码,并存入一个.h文件,这个过程在调用make之后才进行,所以初始情况下你是看不到这个ui_myform.h文件的,只有经过了make过程该头文件才生成。不过没关系,没有这个文件我们照样能写出正确的代码。 单继承方式简单来说就是在代码首先要自定义一个子类(后文称为MyForm),该类要从form对应的窗体类(或其兼容的子类)派生;并用ui生成的类定义一个类里的成员变量(后文成文myui)。这样在MyForm的构造函数可以直接调用myui和myui的变量和函数,使用起来很方便。 举例说明, 比如这里有一个ui文件叫myform.uiui文件里定义的窗体名字为BigWidget,上面摆放了一个单行编辑控件叫lineeditName: //myform.h #include “ui_myform.h” class MyForm: public QWidget { Q_OBJECT public: MyForm(QWidget*parent) { myui.setupUi(this); } private: Ui::BigWidget myui; private: void my_function(); }; 上面这段简单的类的声明是前文所述前三点要点的最佳例证,请对照要点的文字描述和具体的代码体会其的含义。这里还有一点比较有意思的地方,就是ui文件提供的类被包含在了名为Ui的name space里,这样做的目的是将ui文件的命名空间与用户的代码分离,避免两者出现命名冲突的情况。相应的,我们写代码的时候也要注意在使用ui文件的类时要用“Ui::”的方式进行引用。 再来看cpp文件 //myform.cpp #include #include “myform.h” void my_function(void) { QMessageBox::information(this, “Name”, myui.lineeditName->text()); } 这里随便写了一个函数,为了说明如何在窗体类里调用ui文件定义的控件。这段代码非常简单,就不多作说明了。 有了单继承的基础,学习多继承是小菜一碟。来段代码看一下就明白了。 //myform.h #include “ui_myform.h” class MyForm: public QWidget, public Ui::BigWidget { Q_OBJECT public: MyForm(QWidget*parent) { setupUi(this); } private: void my_function(); }; //myform.cpp #include #include “myform.h” void my_function(void) { QMessageBox::information(this, “Name”, lineeditName->text()); } 是不是不用说明大家也能明白呢?多继承其实就是不仅从form需要的窗体类去派生,还要加上ui提供的类本身。这样带来的好处是你的窗体类继承了ui里的所有控件和方法,调用时就可以少写一些字。 单继承和多继承这两种方法没有好坏之分,大家可以根据自己的编程习惯取舍。 第四步,编译、验证在pro文件包含正确FORMS信息的情况下,运行qmake; make就可以编译工程了。 make时如果你认真看一下输出就会发现,make在最开始编译的时候就会自动调用uic去生成需要的代码。经过make之后ui_myform.h文件就生成了,建议大家去看一下这个文件的内容。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlbertOS

还会有大爷会打钱?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值