Qt中的UI文件介绍
UI文件是什么?
.ui.ui.ui通常是指Qt设计师设计出来的界面文件的后缀,它本质上是一个标准XML格式的文本文件,需要通过uicuicuic工具将其转换为项目中可用的ui_∗.hui\_*.hui_∗.h头文件
使用时ui是一个指向这个界面类的指针:
ui−>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_NAMESPACEclass 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);} // setupUivoid 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 UiQT_END_NAMESPACE#endif // UI_MAINWINDOW_H
代码开头的注释提醒开发者不要手动修改该头文件,因为 uic 工具下次自动生成 .h 文件时,会把旧的代码全清掉,然后生成新的代码内容。
QT_BEGIN_NAMESPACE 和 QT_END_NAMESPACE 这两个宏标示中间的代码是包含在名字空间里的,表示中间的代码是被namespace包裹的。
第一个类是全局范围定义的 Ui_MainWindow 类,里面首先定义了一个 label 指针,注意这个指针名称就是之前设计师里显示的 objectName。
接着定义了一个 setupUisetupUisetupUi 函数,它是最关键的生成图形界面的函数,它接收一个 QMainWindowQMainWindowQMainWindow 对象的指针,然后为这个 QMainWindowQMainWindowQMainWindow 对象设置窗口界面和控件。
还有一个 retranslateUi 函数,是专门用于支持多国语言翻译的,主窗口和标签控件的字符串都在这重新翻译一下,如果有多国语言支持的翻译文件,界面的多国语言显示就通过该函数实现。
这两个函数细节就不讲解了,以后还会遇到,而且它们都是 uic 自动生成的,不需要我们手动编写或修改,不用太担心细节,学会用这个头文件就可以了。
接下来定义了一个叫 Ui 的名字空间,空间里定义了一个类 MainWindow ,简单地从 Ui_mainwindow 类继承一下,并没有添加额外的代码。使用 Ui 名字空间的好处就是避免名称冲突,所以正常都不会直接使用 Ui_Mainwindow 类,而是用名字空间里的 Ui::Mainwindow 类。
需要注意的是 ui_hello.h 头文件里没有 Q_OBJECT 宏,它里面定义的类也没有从任何窗口或控件类继承。无论是 UimainwindowUi_mainwindowUimainwindow 类还是 Ui::mainwindowUi::mainwindowUi::mainwindow 类,它们都不是窗口类!
准确地说 它们通过 setupUi 函数,辅助该函数参数里的窗口对象(QMainWindow *MainWindow)构建图形界面,它们帮助别的窗口类对象构建图形界面,仅此而已当然,在 setupUi 函数里新建的控件指针,如 label,是 Ui_mainwindow 或Ui::mainwindow 类里的成员变量,代码里需要通过这个类的成员变量来操控相应的控件。
如果要在项目里面使用 ui 文件(其实是 ui_*.h),通常有三种方式:直接使用方式、多重继承使用方式和成员变量使用方式。
,使用 QtCreatorQt CreatorQtCreator 自动生成的代码就是成员变量使用方式。
成员变量使用方式(自动生成的代码)
我们使用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_OBJECTpublic: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 *uicreateUi.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();
}
编译过程:
- 打开 Qt 命令行工具,进入QtDemo 文件夹
- 用 uic 生成 ui_hello.h:
uic hello.ui -o ui_hello.h
- 用 moc 生成元对象系统代码:
moc hellouiwidget.h -o moc_hellouiwidget.cpp
- 生成可执行程序:
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
- 输入
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的取名都差不多。
Qt中的UI文件介绍相关推荐
- Qt中的ui文件是c语言文件吗,c-Qt-UI文件未在Visual Studio中更新
我最近开始使用Qt(某种速成课程)并将其与Visual Studio集成(如here所述),现在由于某种原因,在进行了以下更改后,文件似乎没有使用保存的.ui文件进行更新. Qt设计器. 该文件正在正 ...
- qt中使用 ui 文件进行界面设计
目录 1.创建 Qt 应用 2.项目创建成功 3.直接点击打开 mainwindow.ui 文件 4.随便从左边侧边栏拖拽一个空间到 界面设计区域 5.在右侧边栏右键点击 pushButton 控件 ...
- Qt探秘——谈ui文件的用法
相信用过Qt Designer的朋友,对Qt Project中的.ui文件并不陌生.这个文件在Qt Designer中并不能直接修改其源代码,而只能通过Qt Designer的图形工具对其进行操作.对 ...
- vs2019工程中打开ui文件就卡死
vs系列文章目录 文章目录 vs系列文章目录 前言 一.解决 1. 选择ui文件 2. 添加打开方式 3.选择打开工具 4.选择designer.exe打开 5. 设置designer.exe默认打开 ...
- 在QT中自定义头文件和源文件的使用方法
在QT中自定义头文件和源文件的使用方法 最近想用QT来实现一个简单的功能,为了便于函数的集成需要将功能函数进行封装,自己补了些c++的函数封装方法,发现在QT中还不太一样.接来下简单介绍一下具体怎么实 ...
- 关于Qt Designer程序/UI文件打开未响应的解决方法
关于Qt Designer程序/UI文件打开未响应的解决方法 参考文章: (1)关于Qt Designer程序/UI文件打开未响应的解决方法 (2)https://www.cnblogs.com/ys ...
- Qt中打开excel文件
qt中打开excel文件有两种方法 第一种,用QAxObject,在使用QAxObject,要在.pro文件中添加QT += axcontainer,同时在调用文件中添加#include <QA ...
- 在Qt中查看.raw文件
在Qt中查看.raw文件 Qt中图像类为QImage,而OpenCV对图像操作使用Mat/IplImage,因此,想要在Qt的控件上查看.raw文件需要先将IplImage/Mat转换为QImage ...
- Qt中的.qrc文件
Qt中的qrc文件 是一个xml格式的资源配置文件,与应用程序关联的应用程序由 .qrc 文件来指定,它用XML记录硬盘上的文件和对应的随意指定的资源名称,应用程序通过资源名称来访问资源.指定的路径是 ...
最新文章
- 自然语言处理(NLP)之用深度学习实现命名实体识别(NER)
- python单词意思-Python这个单词是什么含义??????????????
- python 代码-代码的重试机制(python简单实现)
- 微众WeCross 跨链平台(4)异构链互联协议HIP
- 基于.NET平台常用的框架整理(转)
- 004-React入门概述
- 第十三天-linux正则表达式及重点命令
- pytorch显卡内存随训练过程而增加_PyTorch重大更新:将支持自动混合精度训练!...
- 【编译原理】第一章 引论
- 十一:Cocos2d-x坐标系
- Python使用C++动态库的方法
- MySQL+Navicat安装教程
- 理科生毕业,如何写论文,为论文降重
- 我所完成的探索电影数据集完成报告
- red5-server-1.0.6-RELEASE 启动异常
- csgo红锁号能解锁吗_CSGO红锁黑刀号!重磅!大规模红锁!
- 支付平台网站安全解决方案
- 《流浪方舟》- 废土世界的冒险之旅
- 腾讯课堂直播: 手把手教你开发《3D街头篮球》
- ILDasm和ILAsm简单使用
热门文章
- java循环例题while型_Java基础--while、do-while、for循环结构(附例题)
- 浪潮官网服务器型号,浪潮服务器有哪些型号,哪位了解?
- 金九银十的你准备好了吗?Python 100道基础面试题先收藏!【附答案】
- 事务压缩 对表的影响 compress for oltp
- android 截图模糊,Adobe XD导出图片模糊?设置错误啦(切图详解)
- linux系统与window区别,linux系统和windows系统的区别是什么?
- 纯Web前端打造的元宇宙展厅——开箱即用的Lingo3D游戏引擎 支持原生、React、Vue
- COLMAP: Structure-from-Motion Revisited
- 大学创业是一种什么样的体验(一)
- maven报错:Failed to execute goal on project ...: Could not resolve dependencies for project ...