Qt_控件的QWidget属性介绍

news/2024/9/17 15:15:49/ 标签: qt, 开发语言, c++

目录

1、QWidget的核心属性

2、enabled

3、geometry

3.1 代码测试geometry

4、windowTitle

4.1 代码测试windowTitle

5、windowIcon

5.1 QIcon设置图标

5.2 qrc机制 

5.3 代码测试windowIcon 

6、windowOpacity

6.1 代码测试windowOpacity

7、cursor

7.1 代码测试cursor

8、font 

8.1 代码测试font

9、toolTip

9.1 代码测试toolTip

10、focusPolicy

10.1 代码测试focusPolicy

11、styleSheet 

11.1 代码测试styleSheet 

结语 


前言:

        控件是Qt中非常重要的概念,在Qt中所有的控件都是直接或间接继承自QWidget类。一个完整的界面是由多个控件组成的,因此开发图形化界面就离不开控件。控件英文名为Widget,在Qt中,内置控件包含但不限于按钮,文本、单行输入框,多行输入框,滚动条,下拉框等。并且Qt支持自定义控件,这让开发者得以实现各式各样的DIY控件设计。

1、QWidget的核心属性

        由于Qt中所有的控件都是继承自QWidget类,因此每个控件中都会有QWidget类的属性,在ui文件中,从右边栏中随便拖拽一个控件至界面中,选中该控件,即可在右下角看到该控件里的QWidget属性。示意图如下:

        可以看到QWidget属性内容是非常多的,我们只需要记住一些常用的即可,具体属性介绍如下:

enabled

设置控件是否可使⽤,true 表示可⽤,false 表示禁⽤

geometry

以父元素坐标为原点,设置控件位置和尺⼨,包含x,y,width,height四个部分

windowTitle

设置 widget 标题

windowIcon

设置 widget 图标

windowOpacity

设置 widget 透明度

cursor

设置⿏标悬停时显⽰的图标形状,比如是普通箭头,还是沙漏,还是⼗字等形状

font

设置字体相关属性,比如字体家族,字体大小,粗体,斜体,下划线等等

toolTip

⿏标悬停在控件上会在状态栏中显示的提示信息

toolTipDuring

toolTip 显示的持续时间

minimumSize

控件的最⼩尺⼨,包含最⼩宽度和最⼩⾼度

maximumSize

控件的最⼤尺⼨,包含最⼤宽度和最⼤⾼度

sizePolicy

尺⼨策略,设置控件在布局管理器中的缩放⽅式

2、enabled

        enabled表示设置控件是否可使⽤(默认控件都是可以使用的),在ui文件中可以直接对enabled属性进行勾选。当禁用了一个控件的enabled意味该控件不能接收任何用户的输⼊事件,在外观上往往是灰⾊的且无法选中该控件,如果⼀个控件被禁⽤,则该控件的⼦控件也会被禁⽤。

        示例如下:


        上述是用界面的方式进行禁用,还可以使用代码的方式对控件的enabled属性设置禁用,Qt提供了两个接口如下:

isEnabled() 获取到控件的enabled状态
setEnabled() 参数传true或者false,表示设置控件是否可使⽤

        测试代码如下: 

#include "widget.h"
#include "ui_widget.h"#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* p = new QPushButton("按钮",this);p->setEnabled(false);//该按钮被设置为禁用状态
}Widget::~Widget()
{delete ui;
}

        测试结果进行对比(右图为上述代码的运行结果):

3、geometry

         geometry表示控件所处的位置(横、纵坐标)和控件本身的尺寸(长*宽),用四个属性来表示他们:x(横坐标)、y(纵坐标)、width(宽度)、height(高度)。并且是以父控件的左上角为原点的。

        有了上述四个属性,就可以在界面中描绘处一个控件,不过在此之前,先了解Qt中的坐标系的规定,Qt的坐标系和数学中的笛卡尔坐标系不同,Qt坐标系为左手坐标系,该坐标系的结构如下:


        Qt中提供了两个关于geometry的接口,该接口介绍如下:

geometry() 
//获取到控件的位置和尺⼨. 返回结果是⼀个QRect类型的对象, 
//该对象包含了 x, y, width, height四个成员setGeometry(QRect)
setGeometry(int x, int y,int width, int height)
//设置一个控件的geometry,可以传QRect对象,也可以直接传四个属性

        有了上述的基础概念,就可以对一个控件进行位置和尺寸的设置了。

3.1 代码测试geometry

        实现四个方向按钮来控制另一个按钮的位置,即按下左移按钮,则被控制的按钮向左移动。具体示意图如下:

        实现上下左右四个按钮的槽函数。当按下这四个按钮时会发送对应的信号,这些信号就会触发对应的槽函数,每个槽函数都会使上面的移动按钮向对应方向移动若干距离,槽函数代码如下:

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()//向上移动
{QRect q = ui->pushButton_move->geometry();ui->pushButton_move->setGeometry(q.x(),q.y()-50,q.width(),q.height());
}void Widget::on_pushButton_2_clicked()//向左移动
{QRect q = ui->pushButton_move->geometry();ui->pushButton_move->setGeometry(q.x()-50,q.y(),q.width(),q.height());
}void Widget::on_pushButton_3_clicked()//向下移动
{QRect q = ui->pushButton_move->geometry();ui->pushButton_move->setGeometry(q.x(),q.y()+50,q.width(),q.height());
}void Widget::on_pushButton_4_clicked()//向右移动
{QRect q = ui->pushButton_move->geometry();ui->pushButton_move->setGeometry(q.x()+50,q.y(),q.width(),q.height());
}

        测试结果:

        可以从结果看到,点击左移按钮使,上面的按钮向左移动了,同理其他按钮也是一样的效果。 

4、windowTitle

        该属性顾名思义表示窗口的标题,当我们生成一个界面使,可以看到该界面顶层是有一个标题的,如下图:

        Qt提供了两个对窗口标题操作的接口,如下:

windowTitle() //获取当前窗口的标题setWindowTitle(constQString& title) //设置当前窗口标题//值得注意的是,调用这两个接口的控件的顶层必须有窗口标题,否则调用不会产生效果

4.1 代码测试windowTitle

        通过让widget去调用setWindowTitle函数,达到设置窗口标题的作用,代码如下:

#include "widget.h"
#include "ui_widget.h"#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);this->setWindowTitle("设置窗口标题");
}Widget::~Widget()
{delete ui;
}

        测试结果:

        这里必须要用this指针去调用,因为this指针代表widget,而widget的顶层含窗口标题。不能用一个创建出来的控件去调用setWindowTitle,因为那样做不会产生任何效果。

5、windowIcon

        windowIcon表示窗口的图标,从上面的图片中可以看到窗口标题旁边有一个图标,windowIcon就是描述窗口图标的属性。Qt提供了两个对窗口图标进行操作的接口,接口介绍如下:

windowIcon() //获取窗⼝图标,返回QIcon对象,QIcon就是图标的代码表现形式setWindowIcon(const QIcon& icon) //设置窗⼝图标

        这两个接口的用法逻辑和windowTitle是一样的,只不过把图标封装成QIcon类。并且大部分场景是使用setWindowIcon接口对窗口图标进行设置。

5.1 QIcon设置图标

        将图标所在的路径以字符串的形式传给QIcon,然后把QIcon传给setWindowIcon,此时编译器会依据QIcon里的路径找到这个图标。由于开发的界面程序是要发给用户的,因此也会把对应的图标文件发给用户,一般会使用相对路径的方式,将图标文件扎入至用户的磁盘中。但是这么做会将图标暴露在外,即用户可以删除这个图标文件,这样一来程序就会会问题,所以针对图标存放问题,一般采用qrc机制。

5.2 qrc机制 

        qrc机制解决的两个问题:1、确保图标文件在用户主机上。2、确保图标不会被轻易的删除。 qrc是一种创建虚拟目录,并把图标文件导入到该目录下的方式来解决以上两个问题的,可以理解为图标文件模拟了一个目录环境。生成qrc文件的如下。

        1、点击新建项目,然后选择Qt里的Qt Resource File:

        2、给qrc文件定义一个文件名:

        3、然后一直点击下一步,就生成完毕了:

        4、现在只是创建了qrc文件,还需要在该文件中生成虚拟目录:

        点击add Files会打开一个目录,该目录就是当前代码所在的目录,并且要导入的图标必须该目录下。

        5、点击Add Files后,选择要添加的图标:

        6、最终可以看到虚拟目录下的图标文件,表示添加完成:

        以上就是qlc虚拟目录的创建,后续只需要在代码中将该虚拟目录的路径给到QIcon对象就可以设置窗口图标了。 

5.3 代码测试windowIcon 

        在代码中用刚刚导入的图标文件的路径创建QIcon对象,然后用该对象进行设置图标:

#include "widget.h"
#include "ui_widget.h"#include <QIcon>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QIcon q(":/rose.png");//找到刚刚图标文件的路径this->setWindowIcon(q);
}Widget::~Widget()
{delete ui;
}

        运行结果:

        从结果可以看到,窗口图标已经被更改。 

6、windowOpacity

        windowOpacity表示控件的透明度属性,Qt提供了两个关于此属性的接口:

windowOpacity() 
//获取到控件的不透明数值,返回值的类型为float, 
//范围为0.0 -> 1.0 其中 0.0 表⽰全透明, 1.0 表⽰完全不透明setWindowOpacity(float n)
//设置控件的不透明数值

        即数值越接近0.0则控件的背景是越透明,数值越接近1.0则相反。

6.1 代码测试windowOpacity

         创建两个按钮,一个按钮被点击会增加当前窗口的不透明度,另一个按钮被点击会增加当前窗口的透明度,代码如下:

        定义这两个按钮的槽函数:

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_add_clicked()
{float f = this->windowOpacity();f+=0.1;//增加不透明度this->setWindowOpacity(f);
}void Widget::on_pushButton_sub_clicked()
{float f = this->windowOpacity();f-=0.1;//增加透明度this->setWindowOpacity(f);
}

        运行结果:

7、cursor

         cursor属性表示鼠标的样式,即当鼠标移至控件内时,鼠标的样式会变成该控件cursor属性的样式,可以在ui文件中看到cursor内置的样式:

        此外,Qt还提供了关于cursor属性的三个函数,介绍如下:

cursor() 
//获取到当前控件的cursor属性, 返回QCursor对象
//当⿏标悬停在该控件上时, 就会显⽰出对应的形状.setCursor(const QCursor& cursor) 
//设置⿏标停留在该控件上的光标形状QGuiApplication::setOverrideCursor(const QCursor& cursor)
//设置全局光标的形状,对整个程序中的所有控件都会⽣效
//并且覆盖上⾯的 setCursor 设置的内容.

7.1 代码测试cursor

        可以对上述设置窗口图标的代码进行添加鼠标图标替换功能,代码如下:

#include "widget.h"
#include "ui_widget.h"#include <QIcon>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QIcon q(":/rose.png");//找到刚刚图标文件的路径this->setWindowIcon(q);QPixmap qp(":/rose.png");//用QPixmap的对象来初始化QCursorqp = qp.scaled(100,100);//缩小光标大小QCursor qc(qp);this->setCursor(qc);//设置widget窗口内的鼠标图标
}Widget::~Widget()
{delete ui;
}

        运行结果(由于电脑截图不方便看出效果,因此用手机拍摄):

8、font 

        font表示控件内的字体属性,可以在ui界面中查看font都有哪些属性:

        而在代码中Qt提供两个关于font的函数,介绍如下:

font() 
//获取当前控件的字体信息,这些信息都被保存在QFont里setFont(const QFont& font) 
//传入QFont类型的对象,以设置当前控件的字体信息

8.1 代码测试font

        因此需要对控件中的字体做样式修改,则需要先定义一个QFont对象,在该对象中把各属性的样式都设置好,然后用控件调用setFont函数,并把该对象传给setFont,代码如下:

#include "widget.h"
#include "ui_widget.h"#include <QLabel>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QLabel* label = new QLabel(this);label->setText("hello Qt");QFont qf;qf.setFamily("微软雅黑");qf.setPixelSize(40);qf.setUnderline(true);label->setFont(qf);
}Widget::~Widget()
{delete ui;
}

        测试结果:

9、toolTip

         toolTip顾名思义指的是提示,即当鼠标悬停在控件上时,会出现一个小框框,框里的内容就是自定义的提示说明。并且Qt提供了两个操作toolTip的函数,介绍如下:

setToolTip() 设置悬停时的提⽰说明setToolTipDuring() 设置提示说明的显示时间,单位毫秒

9.1 代码测试toolTip

         代码如下:

#include "widget.h"
#include "ui_widget.h"#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* p = new QPushButton("按钮",this);p->move(300,300);p->setToolTip("这是一个普通的按钮");p->setToolTipDuration(5000);//该提示在5秒后消散}Widget::~Widget()
{delete ui;
}

        测试结果:

10、focusPolicy

        focusPolicy表示焦点政策,该属性表示某个控件能否被⿏标选中或者能否通过tab键选中,比如输入数据至输入框时,首先得用鼠标点击输入框,这个过程就是焦点的选中。当然,输入框默认可以被tab键和鼠标选中,但是label这样的控件默认就是无法选中焦点的。

        Qt提供关于focusPolicy函数的介绍如下:

focusPolicy()//获取控件的焦点,返回值是FocusPolicy,是一个枚举类型setFocusPolicy(Qt::FocusPolicy policy) 设置控件的焦点政策

        首先,FocusPolicy类型有如下常量:

• Qt::NoFocus :控件不会接收焦点
• Qt::TabFocus :控件可以通过Tab键接收焦点
• Qt::ClickFocus :控件可以通过⿏标点击接收焦点
• Qt::StrongFocus :控件可以通过Tab键和⿏标点击接收焦点 (默认值)
• Qt::WheelFocus : 类似于 Qt::StrongFocus , 同时控件也通过⿏标滚轮获取到焦点 (新增
的选项, ⼀般很少使⽤).

10.1 代码测试focusPolicy

        创建一个单行输入框,默认该输入框是可以获得鼠标焦点以及键盘tap焦点的,如下图:

         通过代码可以对该输入框的焦点政策做修改,代码如下:

#include "widget.h"
#include "ui_widget.h"#include <QLineEdit>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QLineEdit* q = new QLineEdit(this);q->move(300,300);q->setFocusPolicy(Qt::NoFocus);//设置该控件不能获取到焦点
}Widget::~Widget()
{delete ui;
}

        运行结果:

11、styleSheet 

        该属性支持QSS对控件的样式进行设置,QSS是CSS的一部分。CSS (Cascading Style Sheets 层叠样式表) 本⾝属于网页前端技术,主要就是用来描述界面的样式,只不过CSS的样式更为丰富,因此Qt同样支持了CSS,不过只支持了其一部分,因此称为QSS。

        其中Qt也提供了一个函数,可以通过该函数完成QSS的样式修改,该函数介绍如下:


QString styleSheet() const//返回当前控件的样式,以字符串的形式返回void setStyleSheet(const QString &styleSheet)//设置当前控件的样式

11.1 代码测试styleSheet 

        这里对QString的格式有要求,即:使用键值对的方式设置样式,其中键和值之间使用 : 分割,:左边是属性,右边是样式。多个键值对之间使⽤ ; 分割。测试代码如下:

#include "widget.h"
#include "ui_widget.h"#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* p = new QPushButton("QSS",this);p->setStyleSheet("color:blue;background-color:green;font-style:italic");
}Widget::~Widget()
{delete ui;
}

        测试结果:

结语 

        以上就是关于QWidget的属性介绍,QWidget是Qt控件中核心的一个类,他提供了控件所需的基本功能,比如尺寸、位置、字体、等基本属性,以及焦点获取(如鼠标点击、键盘输入等)的能力,控件必须有这些属性才能真正意义上的成为一个控件。理解QWidget的基本属性是掌握使用控件的基本条件之一。

        最后如果本文有遗漏或者有误的地方欢迎大家在评论区补充,谢谢大家!!    


http://www.ppmy.cn/news/1525215.html

相关文章

自动化任务的错误处理:编写健壮的自动化脚本,处理Office应用中的错误和异常情况

目录 引言 一、自动化任务概述 二、自动化脚本编写基础 2.1 环境准备 2.2 脚本结构 2.3 示例代码 三、Office应用中的错误和异常情况处理 3.1 文件访问权限问题 3.2 文件格式不兼容 3.3 宏病毒和安全性问题 3.4 控件错误和插件问题 四、异常处理与日志记录 4.1 捕…

Apple M3编译OpenSSL安卓平台SO库

1.下载OpenSSL源码: https://github.com/openssl/openssl.git 2.配置NDK环境变量:vim ~/.zprofile 添加ANDROID_NDK_ROOT环境变量,iosdev改为你自己的用户名 export ANDROID_NDK_ROOT=/Users/iosdev/Library/Android/sdk/ndk/23.1.7779620 添加NDK下可执行文件路径到PATH环…

工具、环境等其他小问题归纳

此篇文章内容会不定期更新&#xff0c;仅作为学习过程中的笔记记录 一、查询Windows 10环境下python版本与安装路径 若电脑成功安装了python环境&#xff0c;不小心忘了版本。 I、查询版本 1、cmd窗口快捷查询 Win R 输入cmd 进入窗口&#xff1b; 直接输入 python --version …

华为 HCIP 认证费用和报名资格

在当今竞争激烈的信息技术领域&#xff0c;华为 HCIP认证备受关注。它不仅能提升个人的技术实力与职业竞争力&#xff0c;也为企业选拔优秀人才提供了重要依据。以下将详细介绍华为 HCIP 认证的费用和报名资格。 一、HCIP 认证费用 华为HCIP认证的费用主要由考试费和培训费构成…

Linux 安装神州通用数据库 ShenTong7.0.8_342.92_linux64

Linux 安装神州通用数据库 ShenTong7.0.8_342.92_linux64 1、准备工作2、安装数据库3、启停数据库4、后续步骤 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Linux环境下安装神州通用数据库&#xff08;ShenTong&#xff09;是一个相对直…

Go中更安全的枚举

iota Go让你用iota来使用枚举。 const (Guest iotaMemberModeratorAdmin )虽然Go是明确的&#xff0c;但iota似乎相对模糊。如果你以任何其他方式对const组进行排序&#xff0c;你会引入副作用。在上面的例子中&#xff0c;你仅仅对第一个参数Guest赋值了。你可以显式地给每…

【前端】vue+html+js 实现table表格展示,以及分页按钮添加

一. 问题描述 数据条数太多显示到页面上时可能会渲染较慢&#xff0c;因此需要截取数据进行展示。 二. 代码写法 思路&#xff1a;按照上述图示思路&#xff0c;需要有两个数据列表&#xff0c;一个存储的是所有的列表数据&#xff0c;一个存储的是展示的数据列表&#xff0c…

jQuery UI API 文档

关于《jQuery UI API 文档》&#xff0c;我找到了一些有用的信息。jQuery UI 是建立在 jQuery JavaScript 库上的一组用户界面交互、特效、小部件及主题。如果您是 jQuery 新手&#xff0c;建议您先查看 jQuery 教程。目前&#xff0c;我找到的资料主要是关于 jQuery UI 1.10 版…

【加密社】深入理解TON智能合约 (FunC语法)

king: 摘要&#xff1a;在TON&#xff08;TheOpenNetwork&#xff09;区块链平台中&#xff0c;智能合约扮演着举足轻重的角色。本文将通过分析一段TON智能合约代码 带领读者学习dict&#xff08;字典&#xff09;和list&#xff08;列表&#xff09;在FunC语言中的用法&#x…

LeetCode_sql_day24(1212.查询球队积分)

描述 表: Teams ------------------------- | Column Name | Type | ------------------------- | team_id | int | | team_name | varchar | ------------------------- team_id 是该表具有唯一值的列。 表中的每一行都代表一支独立足球队。表: Matches…

人工智能 | 搭建企业内部的大语言模型系统

大纲 开源大语言模型大语言模型管理私有大语言模型服务部署方案 开源大语言模型 担心安全与隐私&#xff1f;可私有部署的开源大模型 商业大模型&#xff0c;不支持私有部署 ChatGPTClaudeGoogle Gemini百度问心一言 开源大模型&#xff0c;支持私有部署 MistralMeta Llama…

【LeetCode】:面试题 16.05. 阶乘尾数

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C课程学习 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 好久没有写文章了&#xff0c;今天碰见了一道有趣的题目&#xff0c;写下来分享一下。 &#x1f3c6;1.问题描…

【QT】系统-上

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;QT 目录 &#x1f449;&#x1f3fb;事件QWidget中常见的事件 &#x1f449;&#x1f3fb;处理鼠标事件&#xff1a;leaveEvent和enterEvent&#x1f449;&a…

简单代码实现视频转图片_py

目录 1.安装OpenCV 环境要求 安装命令 验证安装 2. OpenCV用法 3.实现程序 博主最近在研究深度学习&#xff0c;需要收集数据集进行处理&#xff0c;但一张张拍照真是太麻烦了 就想着&#xff0c;哎&#xff0c;能不能写一个程序&#xff0c;把视频转成图片不就行了&am…

tabBar设置底部导航栏

如果应用是一个多 tab 应用&#xff0c;可以通过 tabBar 配置项指定一级导航栏&#xff0c;以及 tab 切换时显示的对应页&#xff0c;简单来说就是像美团外卖下面的导航栏一样可以任意切换 1.首先创建三个页面&#xff0c;在页面里面可以写一些东西或者放一张图片方便区分。 2.…

http网络请求与下载进度

Http_request 目录 一、XMLHttpRequest 在使用 Fetch API 进行网络请求时&#xff0c;原生的 Fetch API 并不直接支持获取下载进度的功能&#xff0c;因为 Fetch API 主要是基于 Promise 的&#xff0c;它主要关注于请求的成功或失败&#xff0c;以及响应数据的处理&#xff…

微信小程序开发——比较两个数字大小

在这里我们使用的工具是 需要自行安装和配置。 在微信小程序中比较两个数字大小有以下几种方式&#xff1a; 一、普通条件判断 在小程序的.js 文件中&#xff0c;先定义两个数字&#xff0c;如let num1 5; let num2 3;。通过if - else if - else语句&#xff0c;根据num1与…

MVC设计模式与delegate,tablview,Appdelegate,SceneDelegate

一、MVC MVC就是Model&#xff08;模型&#xff09;、View&#xff08;视图&#xff09;、Controller&#xff08;控制器&#xff09; 例如上面的 excel表&#xff0c; 数据、数据结构就是模型Model 根据数据形成的直观的、用户能直接看见的柱形图是视图View 数据构成的表格…

假期学习-- iOS 通知详解

iOS 通知详解 数据结构 从我们之前使用通知的流程和代码来看&#xff0c;通知其实就是一个单例&#xff0c;方便随时访问。 NSNotificationCenter&#xff1a;消息中心 这个单例类中主要定义了两个表&#xff0c;一个存储所有注册通知信息的表的结构体&#xff0c;一个保存…

模版方法模式template method

学习笔记&#xff0c;原文链接 https://refactoringguru.cn/design-patterns/template-method 超类中定义了一个算法的框架&#xff0c; 允许子类在不修改结构的情况下重写算法的特定步骤。 上层接口有默认实现的方法和子类需要自己实现的方法