GUI开发基础
🌟项目文件组成
- open QtCreator ---> select Creator Project ---> select Application(Qt)/Qt Widgets Application ---> fix Project Name and Project Path---> select Build System : qmake ---> fix Qt UI Class Name and Base Class Name ---> skip translation ---> select Build Version ---> Completed
完成一个GUI项目的创建,我可以在项目所在文件夹看到一个GUI项目的文件组成。
- .pro文件:存储Qt项目设置的文件。
- .pro.user文件:用于记录打开工程的路径,所用的编译器、构建的工具链、生成目录、打开工程的qt-creator的版本等。 当更换编译环境时,要将其删除。
- main.cpp文件:存放程序入口函数文件,里面通常只包含一个main函数。
- mainwindow.cpp与mainwindow.h文件:是我刚刚创建的窗体类的源文件和头文件。
- mainwindow.ui文件:一个XML格式存储的窗体上的元件及其布局的文件。
✨浅析Pro文件配置
cpp
//QT 字段后关联的是当前开发应用引入的QT模块,core gui是Qt用于GUI设计的类库模块,如果开发控制台程序就不用添加core gui
//pro文件中注释 使用'#'
QT += core gui
# sql Qt提供的数据库模块
# network Qt提供的网络模块
# xml Qt提供的xml文件处理模块
# concurrent Qt提供的一些高级工具,用于并发编程,特别是线程和进程管理。
# axcontainer Qt提供的用于在应用程序中嵌入和管理ActiveX控件的模块。
# webenginewidgets Qt提供的用于在应用程序中嵌入和显示Web内容的模块。
# multimedia Qt提供的用于处理多媒体数据,包括音频、视频、图像等
# multimediawidgets Qt提供的用于创建和处理多媒体小部件(widgets)的库
//如果高于Qt版本,QT引入widgets模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
//CONFIG 指定项目配置和编译器选项。这些值在内部通过Qmake识别,具有特殊的含义。
CONFIG += c++17
# c++11 支持C++11语法。
# c++17 支持C++17语法。
# release 当前项目已发布模式构建。
# debug 当前项目已调试模式构建。ps:如果指定了有多个构建模式,以最后一个为生效版本。
# debug_and_release 当前项目构建debug和release两种模式。ps:一般可以去除这个选项,不然生成的路径下会创建debug和release两个不同的文件夹
# debug_and_release_target 默认设置此选项。如果还设置了debug_and_release,则调试和发布构建最终会在单独的调试和发布目录中。
# build_all 当前项目的debug和release版本都会被构建
//定义项目名称
TARGET = GUIDemo
//输出目录 $$PWD 表示PRO文件的位置 ./ 表示exe文件的位置
DESTDIR = $$PWD/../bin
//库文件目录 用于引入库文件路径
INCLUDEPATH += \
//依赖文件目录
DEPENDPATH += \
//SOURCES 引入当前项目需要构建的源文件
SOURCES += \
main.cpp \
mainwindow.cpp
//HEADERS 引入当前项目需要构建的头文件
HEADERS += \
mainwindow.h
//FORMS 引入当前项目需要构建的UI文件
FORMS += \
mainwindow.ui
🌟Qt设计师
-
📗Qt设计师是一个用于设计和使用图形用户界面(GUI)的工具,它基于Qt部件(Widgets)进行工作。
-
📕通过Qt设计师,用户可以以所见即所得的方式构建和定制自己的窗口(Windows)或对话框(Dialogs),并提供了不同的方法来测试它们。
-
📘Qt设计师的核心优势在于其强大的信号-槽机制,能够无缝地将由Qt设计师创建的部件或窗体与手工编写的代码整合在一起,从而轻松地为图形元素定义行为。
-
📙此外,Qt设计师设置的所有属性均可以在代码中动态地修改,增加了其灵活性和可扩展性。
-
📓QtCreator这个IDE中已经集成了Qt设计师在其中,用户可以通过(快捷键Shift+F4)编辑窗口类的.ui文件来进入UI设计师界面。此外,QtCreator提供了独立的Qt设计师应用,方便用户在Visual Studio上通过Qt设计师来开发Qt图形界面。
下图是Qt设计师界面:
- 布局和界面设计工具栏:窗口上方的一个工具栏,工具栏的按钮主要实现布局和界面设计。
- 对象浏览器(Object Inspector):窗口右上方的是Object Inspector,用树状视图显示窗体上各组件之间的布局包含关系,视图有两列,显示每个组件的对象名称和类名称。
- 属性编辑器(Property Editor):窗口右下方是属性编辑器,是界面设计时最常用到的编辑器。属性编辑器显示某个选中的组件或窗体的各种属性及其取值,可以在属性编辑器里修改这些属性的值。(PS:1.属性编辑器是按照组件的继承关系来展示属性值配置的。2.组件的属性值还可以在程序运行时来动态配置,通过代码来进行UI设计。)
🌟剖析UI文件运行机制
项目中的窗口类是如何与UI文件绑定的?
📖mainwindow.h解析:
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
//这里通过Qt的宏定义了Ui命名控件,你会发现Ui的类名竟然和窗口类的名称相同,这里的类名并不是当前类的名称
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
//这里定义了一个指针,指向可视化设计的界面,在当前类中访问绑定的UI类的组件,都需要通过这个指针ui来访问。
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
📖mainwindow.cpp解析:
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"//这个文件在我们创建项目时并没存在,它是在qmake编译项目时才会生成。
//执行父类QMainWindow的构造函数,创建Ui:MainWindow类的对象ui。这ui就是MainWindow中private部分定义的指针变量ui。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
//执行了Ui:MainWindow类的setupUi()函数,这个函数实现窗口的生成与各种属性的设置、信号与槽的关联。
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
//简单地删除用new创建的指针ui。
delete ui;
}
📖mainwindow.ui解析:
cpp
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar"/>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
//定义了窗口类中所有组件的属性、布局信息。
📖ui_mainwindow.h解析:
cpp
/********************************************************************************
** 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/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QWidget *centralwidget;
QMenuBar *menubar;
QStatusBar *statusbar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(800, 600);
centralwidget = new QWidget(MainWindow);
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
MainWindow->setCentralWidget(centralwidget);
menubar = new QMenuBar(MainWindow);
menubar->setObjectName(QString::fromUtf8("menubar"));
MainWindow->setMenuBar(menubar);
statusbar = new QStatusBar(MainWindow);
statusbar->setObjectName(QString::fromUtf8("statusbar"));
MainWindow->setStatusBar(statusbar);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MainWindow", nullptr));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
通过查看ui_mainwindow.h文件的内容,发现它主要做了下面一些工作:
- 定义了一个Ui_MainWindow类,用于封装可视化设计的界面。
- 自动生成了界面各组件的类成员变量定义。在public部分为界面上每个组件定义了一个指针变量,变量的名称就是用户自定义的ObjectName。
- 定义了setupUi()函数,这个函数用于创建各个界面组件,并设置其位置、大小、文字内容、字体等属性,设置信号与槽的关联。
接下来,setupUi() 调用了函数 retranslateUi(MainWindow),用来设置界面各组件的文本内容属性,如标签的文字、按键的文字、窗体的标题等 。将界面上的文字设置的内容独立出来作一个函数retranslateUi (),在设计多语言界面才会用到这个函数。(PS:在使用Qt提供的语言家设计多语言版本时,可以为界面中所有控件的文本重新命名。)
🌟UI设计方式
在Qt Creator中,UI设计主要分为两种方式:可视化UI设计和代码化UI设计。这两种方法各有优点,适用于不同的开发需求和场景。
✨可视化UI设计
📘可视化UI设计是通过Qt Creator内置的图形化设计工具(Qt Designer)来创建用户界面的方式 。开发者可以直接拖放控件到窗体上,调整属性和布局,而无需编写代码。
这种方法通常涉及以下步骤:
- 拖放控件:从工具箱中拖放各种UI控件(如按钮、标签、文本框等)到设计窗口。
- 设置属性:通过属性编辑器调整控件的属性,如大小、位置、文本、颜色等。
- 布局管理:使用布局管理器(如水平布局、垂直布局、网格布局等)组织控件,以确保界面在不同窗口大小下的自适应。
- 信号与槽:在设计器中连接控件的信号与槽,实现控件之间的交互。
👍优点:
- 直观性强:通过图形化界面,设计过程更加直观和可视化。
- 效率高:无需编写大量的UI代码,设计速度快。
- 易于调整:可以直接在设计器中调整和查看UI效果。
👎缺点:
- 灵活性有限:对于一些复杂的界面和动态生成的控件,可能不如代码化设计灵活。
- 学习成本:需要熟悉Qt Designer的使用。
✨代码化UI设计
📘代码化UI设计是通过编写代码来创建和管理用户界面的方式 。开发者使用Qt的C++或Python(通过PyQt或PySide)来手动定义控件、布局和交互逻辑。
这种方法通常涉及以下步骤:
- 定义控件:在代码中创建UI控件对象(如QPushButton、QLabel等)。
- 设置属性:通过代码设置控件的属性,如文本、大小、位置等。
- 布局管理:使用布局管理器对象(如QHBoxLayout、QVBoxLayout等)组织控件。
- 信号与槽:通过代码连接控件的信号与槽,实现交互逻辑。
👍优点:
- 灵活性强:可以实现高度自定义和复杂的UI设计,适合动态生成控件的场景。
- 可维护性:对于习惯代码化管理的开发者,更容易进行版本控制和代码管理。
- 更强的控制:开发者可以对控件的创建和管理进行精细控制。
👎缺点:
- 开发速度慢:需要编写大量的代码,初期开发速度较慢。
- 复杂性高:对于大型界面和复杂布局,代码化设计可能更加繁琐。
综合考虑
在实际开发中,很多开发者会综合使用这两种方法 。例如,可以通过可视化UI设计快速创建初始界面,然后在代码中进行进一步的自定义和逻辑处理。这样既能提高开发效率,又能保证灵活性和可维护性。对于简单和标准化的界面设计,可视化UI设计更为合适;而对于需要高度定制和动态生成的界面,代码化UI设计则更为适用。