当前位置: 首页 > news >正文

斗破QT编程入门系列之四:GUI应用程序设计基础:UI文件设计原理与运行机制(五星斗师)

斗破Qt目录:

斗破Qt编程入门系列之前言:认识Qt:Qt的获取与安装(四星斗师)
斗破QT编程入门系列之一:认识Qt:初步使用(四星斗师)
斗破QT编程入门系列之二:认识Qt:编写一个HelloWorld程序(四星斗师)
斗破QT编程入门系列之三:GUI应用程序设计基础:UI文件(四星斗师)
斗破QT编程入门系列之四:GUI应用程序设计基础:UI文件设计原理与运行机制(五星斗师)

参考书籍

《Qt5.9 C++开发指南》

斗破观看顺序:

https://v.haohuitao.cc/yhplay/336-1-2.html
第一季☞第二季前2集☞特别篇1☞第二季3~12集☞特别篇2沙之澜歌☞第三季☞第四季☞三年之约☞缘起☞年番
斗气大陆等级:
斗气有十一个阶别,斗之气,斗者,斗师,大斗师,斗灵,斗王,斗皇,斗宗,斗尊,斗圣,斗帝。
斗气大陆上很久没有出现过斗帝了。

一、参加炼药师竞赛

萧炎控制异火进入纳兰桀体内,为其祛除烙毒,而毒素却意外凶猛与顽固,并不能一次将其彻底清除。诡异的毒素也悄悄跟随着异火侵入了萧炎的体内,修炼时萧炎意外的发现,烙毒中蕴含着大量精纯的能量,一举使自己能力大增。
萧炎来到炼药师集会,想在这里看看能不能找到自己需要的药材,并在这里遇到了黑岩城的琳菲,并同时解救被商家欺负的雪魅。并在会长弗兰克和奥托大师的邀请下参加了加玛帝国的炼药师比赛,当然萧炎也是为了能获得恢复灵魂力量的药方–融灵丹,而美杜莎女王也急需这种物品来恢复自己的蛇人之身,命令萧炎一定要拿到此物。

二、UI文件设计原理与运行机制

为了搞清楚窗体类的定义,以及界面功能的实现原理,这里将项目进行编译。编译后在项目目录下会自动生成一个文件ui_widget.h,这样对于一个窗体,就有4个文件了,各个文件的功能说明如下:
在这里插入图片描述
下面分别分析各个文件的内容及其功能,以及它们是如何联系在一起工作的,实现界面的创建与显示的。

  1. widget.h文件

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

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;
};
#endif // WIDGET_H

widget.h文件有几个重要的部分。
(1)namespace声明
代码中有如下的一个namespace声明:

namespace Ui { class Widget; }

这是声明了一个名称为Ui的命名空间(namespace),包含一个类Widget。但是这个类Widget并不是本文件里定义的类Widget,而是ui_widget.h文件里定义的类,用于描述界面组件的。这个声明相当于一个外部类型声明(具体要看完ui_widget.h文件内的解释之后才能搞明白)。
(2)Widget类的定义。widget.h文件的主体部分是一个继承于QWidget的类Widget的定义,也就是本实例的窗体类。
在Widget类中使用了宏Q_OBJECT,这是使用Qt的信号与槽(signal和slot)机制的类都必须加入的一个宏(信号与槽在后面详细介绍)。
在public部分定义了Widget类的构造函数和析构函数。
在private部分又定义了一个指针。

    Ui::Widget *ui;

这个指针是用前面声明的namespace Ui里的Widget类定义的,所以指针ui是指向可视化设计的界面,后面会看到要访问界面上的组件,都需要通过这个指针ui。
2.widget.cpp文件
widget.cpp文件是类Widget的实现代码,下面是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;
}

注意到,在这个文件的包含文件部分自动加入了如下一行内容:

#include "ui_widget.h"

这个就是Qt编译生成的与UI文件widget.ui对应的类定义文件。
3.widget.ui文件
widget.ui是窗体界面定义文件,是一个XML文件,定义了窗口上的所有组件的属性设置、布局,及其信号与槽函数的关联等。用UI设计器可视化设计的界面都由Qt自动解析,并以XML文件的形式保存下来。在设计界面时,只需要再UI设计器里进行可视化设计即可,而不用管widget.ui文件是怎么生成的。
下面是widget.ui文件的内容。

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>Widget</class><widget class="QWidget" name="Widget"><property name="geometry"><rect><x>0</x><y>0</y><width>800</width><height>600</height></rect></property><property name="windowTitle"><string>Widget</string></property></widget><resources/><connections/>
</ui>

4.ui_widget.h文件
ui_widget.h是在对widget.ui文件编译后生成的一个文件,ui_widget.h会出现在编译后的目录下,或与widget.ui同目录(与项目的shadow build编译设置有关)。
注意: ui_widget.h是对widget.ui文件编译后自动生成的,widget.ui又是通过UI设计器可视化设计生成的。所以,对ui_widget.h手工进行修改没有什么意义,所有涉及界面的修改都应该直接在UI设计器里进行,所以,ui_widget.h也没有必要添加到项目里。
下面是ui_widget.h文件的内容

/********************************************************************************
** Form generated from reading UI file 'widget.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_WIDGET_H
#define UI_WIDGET_H#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>QT_BEGIN_NAMESPACEclass Ui_Widget
{
public:QPushButton *pushButton;QLabel *label;void setupUi(QWidget *Widget){if (Widget->objectName().isEmpty())Widget->setObjectName(QString::fromUtf8("Widget"));Widget->resize(800, 600);pushButton = new QPushButton(Widget);pushButton->setObjectName(QString::fromUtf8("pushButton"));pushButton->setGeometry(QRect(190, 200, 93, 28));label = new QLabel(Widget);label->setObjectName(QString::fromUtf8("label"));label->setGeometry(QRect(170, 150, 151, 16));retranslateUi(Widget);QObject::connect(pushButton, SIGNAL(clicked()), Widget, SLOT(close()));QMetaObject::connectSlotsByName(Widget);} // setupUivoid retranslateUi(QWidget *Widget){Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));pushButton->setText(QCoreApplication::translate("Widget", "PushButton", nullptr));label->setText(QCoreApplication::translate("Widget", "Hello world", nullptr));} // retranslateUi};namespace Ui {class Widget: public Ui_Widget {};
} // namespace UiQT_END_NAMESPACE#endif // UI_WIDGET_H

查看ui_widget.h文件的内容,发现它主要做了以下的一些工作。
(1)定义了一个类Ui_Widget,用于封装可视化设计的界面。
(2)自动生成了界面各个组件的类成员变量定义。在public部分为界面上每个组件定义了一个指针变量,变量的名称就是设置的objectName。比如,在窗体上放置了一个QLabel和一个QPushButton并命名后,自动生成的定义是:

    QPushButton *pushButton;QLabel *label;

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

        QObject::connect(pushButton, SIGNAL(clicked()), Widget, SLOT(close()));QMetaObject::connectSlotsByName(Widget);

第1行时调用connect()函数,将在UI设计器里设置的信号与槽的关联转换为语句。这里是将pushButton按键的clicked()信号与窗体Widget的close()槽函数关联起来,当单击pushButton按钮时,就会执行Widget的close()槽函数,而close()槽函数的功能是关闭窗口。
第2行事设置槽函数的关联方式,用于将UI设计器自动生成的组件信号的槽函数与组件信号相关联。
所以,在Widget的构造函数里调用ui->setupUI(this),就是实现了窗体上组件的创建、属性设置、信号与槽的关联。
(4)定义namespace Ui,并定义一个从Ui_Widget继承的类Widget.

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

本节课最精华的部分来了,这也是Qt界面编程的底层设计:
ui_widget.h文件里实现界面功能的类是Ui_Widget。再定义一个类Widget从Ui_Widget继承而来,并定义在namespace Ui里,这样Ui::Widget与widget.h里的类Widget同名,但是用namespace区分开来。所以,界面的Ui::Widget类与文件widget.h里定义的Widget类实际上是两个类,但是Qt的处理让用户感觉不到Ui::Widget类的存在,只需要知道在Widget类里用ui指针可以访问可视化设计的界面按钮就可以了。

三、英语

先看几个单词:

  • file 文件
  • theory 原理
  • work 工作
  • mechanism 机制

再看几个句子:

  • Burning poison(烙毒) contains(包含) a large amount of pure(纯的) energy, which greatly(极大地) enhances(增强) one’s abilities in one fell swoop(一下子)
  • 烙毒中蕴含着大量精纯的能量,一举使自己能力大增

包含最容易想到的是has,比较地道的用contains。
a large amount of 表示大量
增加比较容易想到的是increase,但是能力的增强用enhances比较地道。
最后一个短语in one fell swoop 表示一蹴而就、一下子,原意是“一下子向下俯冲”。


http://www.mrgr.cn/news/70863.html

相关文章:

  • 一个win32 / WTL下多线程库(CThread类)的使用心得
  • 点云论文阅读-1-pointnet++
  • 在 ALV 报表中使用 CL_SALV 类时,如何处理多行?
  • C# 集合与泛型
  • 微波无源器件 OMT1 一种用于倍频程接收机前端的十字转门四脊正交模耦合器(24-51GHz)
  • 【Linux】获得同一子网下当前在线设备IP/Latency/MAC 通过nmap指定CIDR扫描当前在线设备
  • 腾讯云边缘安全加速平台EdgeOne最佳实践
  • 拾贝(Shibei):微信读书笔记管理的新篇章
  • 如何使用Flask编写一个网站
  • Ubuntu 20.04配置ollama并下载安装调用本地大语言模型
  • 探索jQuery与原生JavaScript:事件绑定的比较
  • 网页直播/点播播放器EasyPlayer.js播放器OffscreenCanvas这个特性是否需要特殊的环境和硬件支持
  • 【Kettle实战】按日期变量批量执行任务[附全部job和tras配置图]
  • 河南测绘资质办理注意事项
  • AI 大模型如何重塑软件开发流程与模式
  • 深入理解Python字符串:常用查找方法、去除首位信息、大小写转换与排版
  • Elasticsearch(ES)简介
  • 群晖NAS上部署Photopea并实现随时随地高效图片处理
  • 2024下半年软考系统架构师案例分析题试题与答案--Cache-aside
  • debug
  • Nginx 部署负载均衡服务全解析
  • 文章管理系统微信小程序ssm+论文源码调试讲解
  • JMeter进阶篇
  • 一、HTML
  • 【代码管理之道】Git基础知识详解
  • java---认识异常(详解)