【Qt】控件概述(3)—— 显示类控件
显示类控件
- 1. QLabel——标签
- 1.1 setPixmap设置图片
- 1.2 setAlignment设置文本对齐方式
- 1.3 setWordWrap设置自动换行
- 1.4 setIndent设置缩进
- 1.5 setMargin设置边距
- 1.6 body
- 2. QLCDNumber
- 2.1 使用QTimer实现一个倒计时效果
- 2.2 使用循环的方式实现倒计时
- 3. QProgressBar——进度条
- 4. QCalendarWidget——日历
1. QLabel——标签
QLabel可以用来显示文本和图片:
| 属性 | 说明 |
|---|---|
| text | QLabel中的文本 |
| textFormat | 文本格式:1:Qt::PlaintText纯文本,2:RichText富文本,3:MarkDownText markdown格式,4:Qt:AutoText根据文本内容自动决定文本格式 |
| pixmap | QLabel内的图片 |
| scaldContents | 设置未true表示自动拉伸填充QLabel,设置为false则不会自动填充 |
| alignment | 表示对齐方式,可以设置为水平对齐和垂直对齐 |
| wordWrap | 自动换行设置,设置为true表示开启,设置为false表示不开启 |
| indent | 文本缩进,水平和垂直都可以生效 |
| margin | 表示文本和边框之间的距离,在上下左右四个方向生效 |
| openExternalLinks | 是否允许打开一个外部链接(当Qlabel涉及到url的时候) |
| buddy | 给QLabel关联一个“伙伴”,当点击QLabel时就会激活对应的“伙伴” |
1.1 setPixmap设置图片
代码样例:Label显示图片
虽然前面讲的QPushButton也可以通过setIcon的方式进行添加图片,但是大多数时候我们更希望使用QLabel来进行添加一个更单纯的一个图片。
- 首先同样讲图片以qrc的方式添加到Qt中
- 创建Label,并可以通过pixmap进行添加图片
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QLabel* label = new QLabel(this);// 设置标签的大小和Widget窗口的大小是一样的QRect rect = this->geometry();label->setGeometry(0, 0, rect.width(), rect.height());// 插入图片并设置图片大小QPixmap pixmap(":/qt.jpg");pixmap = pixmap.scaled(rect.width(), rect.height());// 也可以直接使用自动填充,让图片自动贴合标签的大小// label->setScaledContents(true);label->setPixmap(pixmap);
}
但是这个时候我们是可以对Widget的窗口进行调整大小的,而在我们进行调整大小的时候,我们的标签是不会跟着改变的,所以这里我们需要提供一个事件。也就是说当我们在调整Widget的时候QWidget会触发一个事件resizeEvent事件,也就是说当Widget窗口大小发生变化的时候QWidget 会自动进行调用,而这个时候我们想要Widget进行调用,就可以在Widget中重写这个resizeEvent实现多态,这样只要窗口发生变化就会通过多态调用Widget中的resizeEvent(这个事件我们后面会详细进行讲解),所以我们就可以自定义函数来完成这一操作。

// 在widget.h中添加函数声明
void resizeEvent(QResizeEvent *event); // 这个是QWidget中有的
void Widget::resizeEvent(QResizeEvent *event)
{label->setGeometry(0, 0, event->size().width(), event->size().height());label->setScaledContents(true);qDebug() << event->size();
}
1.2 setAlignment设置文本对齐方式
首先为了我们方便观察,我么需要给label设置一个外边框,我们可以在ui界面中进行设置。

QFrame是QLabel的父类,其中frameShape属性用来设置边框属性。
- QFrame::Box :矩形边框
- QFrame::Panel :带有可点击区域的⾯板边框
- QFrame::WinPanel :Windows风格的边框
- QFrame::HLine :水平线边框
- QFrame::VLine :垂直线边框
- QFrame::StyledPanel :带有可点击区域的⾯板边框,但样式取决于窗口主题
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->label->setText("这是一个水平居中和垂直居中");// 设置文本的对齐方式// 设置方式 水平方向 | 垂直方向ui->label->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
}
而设置垂直方向和水平方向的对齐方式其实就是宏。
enum AlignmentFlag {AlignLeft = 0x0001, AlignLeading = AlignLeft,AlignRight = 0x0002,AlignTrailing = AlignRight,AlignHCenter = 0x0004,AlignJustify = 0x0008,AlignAbsolute = 0x0010,AlignHorizontal_Mask = AlignLeft | AlignRight | AlignHCenter | AlignJustify | AlignAbsolute,AlignTop = 0x0020,AlignBottom = 0x0040,AlignVCenter = 0x0080,AlignBaseline = 0x0100,// Note that 0x100 will clash with Qt::TextSingleLine = 0x100 due to what the comment above// this enum declaration states. However, since Qt::AlignBaseline is only used by layouts,// it doesn't make sense to pass Qt::AlignBaseline to QPainter::drawText(), so there// shouldn't really be any ambiguity between the two overlapping enum values.AlignVertical_Mask = AlignTop | AlignBottom | AlignVCenter | AlignBaseline,AlignCenter = AlignVCenter | AlignHCenter};

1.3 setWordWrap设置自动换行
如果我们使用在label中输入了一行很长的文本而没有自动换行,就会导致部分文本被覆盖而无法显示。
ui->label->setText("这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,");

ui->label->setText("这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,");
ui->label->setWordWrap(true);

1.4 setIndent设置缩进
一般我们在书写word的时候使用的都是首行缩进,但是在Qt中,这里的缩进是对所有行都适用的,不单单是首行缩进
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->label->setText("这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,");ui->label->setWordWrap(true);ui->label->setIndent(50); // 单位像素
}

1.5 setMargin设置边距
我们先直接讲对齐方式改为水平左对齐,垂直上对其。
ui->label->setText("这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,");
ui->label->setWordWrap(true);
ui->label->setAlignment(Qt::AlignLeft | Qt::AlignTop);

设置margin后
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->label->setText("这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,");ui->label->setWordWrap(true);ui->label->setAlignment(Qt::AlignLeft | Qt::AlignTop);ui->label->setMargin(20);
}

1.6 body
我们可以创建两个label和两个radioButton,将其两两关联。然后可以使用快捷键的方式进行选择。

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->label->setBuddy(ui->radioButton);ui->label_2->setBuddy(ui->radioButton_2);
}
这样就可以使用 alt + a选择1,alt+b选择2了。而如果想要做到这样的效果也需要遵循一些规则,也就是使用&A(& + 快捷键)这样的形式才可以做到。
2. QLCDNumber
QLCDNumber是一个专门用来显示数字的控件。
| 属性 | 说明 |
|---|---|
| intValue | QLCDNumber显示数字的值(int) |
| value | QLCDNumber显示的数字值(double),和intValue是联动的,例如value为1.2,那么intValue就是1,另外value和intValue的方法名在位display,而不是setValue或者setValue了 |
| digitCount | 显示数字的位数 |
| mode | 显示数字的模式。1:QLCDNubmer::Dec,十进制。2:QLCDNubmer::Hex,十六进制。3:QLCDNubmer::Bin,二进制。4:QLCDNubmer::Oct,八进制。 |
| segmentStyle | 设置显示风格,1:QLCDNumber::Flat,平面显示风格,数字呈现在一个平坦的表面上。2:QLCDNumber::Outline,轮廓显示风格,数字具有轮廓和阴影效果。3:QLCDNumber::Filled,填充风格,数字可以填充颜色与背景进行区分。 |
2.1 使用QTimer实现一个倒计时效果
代码样式:显示一个倒计时效果
在此之前介绍一个了QTimer类,这个类是Qt封装的一个定时器,可以通过start方法启动定时器,并通过传递参数的方式进行设定定时周期。而QTimer中有一个信号timeout,会根据周期定期的触发timeout信号,这样我们可以把周期设置为1秒,就可以首先一个简单的定时器了。
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 创建一个定时器类time = new QTimer(this);ui->lcdNumber->display(10);connect(time, &QTimer::timeout, this, &Widget::handle);// 启动定时器time->start(1000); // 单位毫秒
}Widget::~Widget()
{delete ui;
}void Widget::handle()
{// 获取当前lcdNumnber值int num = ui->lcdNumber->value();if (num <= 0){// 关闭定时器time->stop();return;}// 设置值ui->lcdNumber->display(num - 1);
}
2.2 使用循环的方式实现倒计时
针对上述存在两个问题。
- 我们先使用最为平常的for循环进行实现,使用Sleep的方式实现。而Sleep是windows的需要包含"windows.h",那是Qt并没有相关的api,但是C++11 中引路了sleep是thread库中的sleep_for
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->lcdNumber->display(10);int value = ui->lcdNumber->value();while(true){std::this_thread::sleep_for(std::chrono::seconds(1));if (value <= 0){break;}value -= 1;ui->lcdNumber->display(value);}
}
这样明显是没法显示出来的,因为whiel循环是在Widget的构造函数中实现的,而窗口的显示是在Widget类实例化后使用w.show()进行实现的,所以是等到while循环结束后,才会调用窗口显示函数进行窗口展示。
- 所以这里我们就想到使用子线程来进行修改
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->lcdNumber->display(10);std::thread t([this](){int value = ui->lcdNumber->value();while(true){std::this_thread::sleep_for(std::chrono::seconds(1));if (value <= 0){break;}value -= 1;ui->lcdNumber->display(value);}});
}
上述通过子线程的方式修改GUI上的内容同样是不行的,在Qt中规定,任何对GUI上内容的操作,必须是主线程中完成的。这样的约定主要是因为GUI中的状态往往是牵一发东全身,就需要同步的对其他内容进行调整。比如调整了某个元素的尺寸,就可能影响到内部的文字位置,或者其他元素的位置.这里⼀连串的修改,都是需要按照⼀定的顺序来完成的.由于多线程执行的顺序无法保障,因此Qt从根本上禁止了其他线程修改GUI状态,避免后续的⼀系列问题.
3. QProgressBar——进度条
核心属性:
| 属性 | 说明 |
|---|---|
| minimum | 进度条最小值 |
| maximum | 进度条最大值 |
| value | 进度条当前值,同上 |
| alignment | 文本在进度条中的对齐方式. 同上 |
| textVisible | 进度条的数字是否可见 |
| orientation | 进度条的方向是水平还是垂直 |
| invertAppearance | 是否是朝反方向增长进度 |
| textDirection | 文本的朝向. |
| format | 展示的数字格式. 1:%p :表示进度的百分比(0-100),2:%v :表示进度的数值(0-100),3:%m :表示剩余时间(以毫秒为单位),4:%t :表示总时间(以毫秒为单位) |
代码样例:实现一个进度条
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);time = new QTimer(this);connect(time, &QTimer::timeout, this, &Widget::handle);time->start(100);
}Widget::~Widget()
{delete ui;
}void Widget::handle()
{int value = ui->progressBar->value();if (value >= 100){time->stop();return;}ui->progressBar->setValue(value + 1);
}
这里我们看到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();void handle();private:Ui::Widget *ui;QTimer* time;
};
#endif // WIDGET_H
从上述代码中我们可以发现一个小细节,就是Widget.h中明明使用了QTimer类,但是并没有包含QTimer头文件#include < QTimer >,而且还没有编译报错。这是应为Qt做了一些特殊处理,在Qt中专门有一个头文件,这个头文件包含了Qt中所有类的“前置声明”形如(class QTimer; class QWidget……),而这个头文件一般不会直接接触到,而是包含在其他的Qt的头文件中,所以在继承的时候就间接的包含这个头文件,所以就可以使用一些类在头文件中声明各种类的指针或者了引用。
而这样的做的目的就是减少编译时的运行时间,应为在C/C++编译期间是要讲头文件进行展开的,而对于一个大型的项目来讲,不乏会包含大量的头文件,而这也间接的增加了编译的时间,所以在头文件声明之处就可以使用这样的前置声明的技术来减少头文件的包含,也可以做到间接减少编译的时间。
但是在C++20后就开始使用module来代替#include,这样也是为了减少编译时的时间消耗。
同样进度条也是可以设置样式的。可以通过ui界面的熟悉面板进行设置,也可以使用代码进行设置。

4. QCalendarWidget——日历
核心属性:
| 属性 | 说明 |
|---|---|
| selectDate | 当前选中的日期,返回一个QDate类型 |
| minimumDate | 最小日期 |
| maximumDate | 最大日期 |
| firstDayOfWeek | 每周的第⼀天(也就是日历的第⼀列)是周几. |
| gridVisible | 是否显示表格的边框 |
| selectionMode | 是否允许选择日期 |
| navigationBarVisible | 日历上方标题是否显示 |
| horizontalHeaderFormat | 日历上方标题显示的日期格式 |
| verticalHeaderFormat | 日历第⼀列显示的内容格式 |
| dateEditEnabled | 是否允许日期被编辑 |
重要信号:
| 信号 | 说明 |
|---|---|
| selectionChanged(const QDate&) | 当选中的日期发生改变时发出 |
| activated(const QDate&) | 当双击⼀个有效的日期或者按下回车键时发出,形参是⼀个QDate类型,保存了选中的日期 |
| currentPageChanged(int, int) | 当年份月份改变时发出,形参表示改变后的新年份和月份 |
void Widget::on_calendarWidget_selectionChanged()
{QDate date = ui->calendarWidget->selectedDate();ui->label->setText(date.toString());
}

相关文章:
【Qt】控件概述(3)—— 显示类控件
显示类控件 1. QLabel——标签1.1 setPixmap设置图片1.2 setAlignment设置文本对齐方式1.3 setWordWrap设置自动换行1.4 setIndent设置缩进1.5 setMargin设置边距1.6 body 2. QLCDNumber2.1 使用QTimer实现一个倒计时效果2.2 使用循环的方式实现倒计时 3. QProgressBar——进度…...
数据库管理-第247期 23ai:全球分布式数据库-Schema对象(20241004)
数据库管理247期 2024-10-04 数据库管理-第247期 23ai:全球分布式数据库-Schema对象(20241004)1 分区、表空间和Chunk(块)2 表空间组3 分片表4 分片表族5 复制表6 在所有分片上创建的非表对象总结 数据库管理-第247期 …...
Docker搭建一款开源的文档管理系统
1.系统介绍 Wizard是一款开源的文档管理系统,它支持多种格式类型的文档管理,包括Markdown、Swagger和Table,以适应不同场景和需求下的文档管理需求。 1.1功能特点 开源免费:Wizard是一款完全免费的开源项目,用户可以…...
软件验证与确认实验一:静态分析
目录 1. 实验目的及要求.................................................................................................... 3 2. 实验软硬件环境.................................................................................................... 3 …...
基于SpringBoot+Vue的高校运动会管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
什么东西可以当做GC Root,跨代引用如何处理?
引言 在Java的垃圾回收机制中,GC Root(Garbage Collection Root,垃圾回收根)是垃圾回收器判断哪些对象是可达的,哪些对象可以被回收的起点。GC Root通过遍历对象图,标记所有可达的对象,而那些不…...
Python深度学习:从神经网络到循环神经网络
Python深度学习:从神经网络到循环神经网络 目录 ✨ 神经网络基础 1.1 🔍 前向传播与反向传播🎨 卷积神经网络(CNN) 2.1 🖼️ 图像分类任务的实现 2.2 🚀 常用架构(LeNet、VGG、Res…...
C++输⼊输出
1.<iostream> 是 Input Output Stream 的缩写,是标准的输⼊、输出流库,定义了标准的输⼊、输 出对象 2.std::cin 是 istream 类的对象,它主要⾯向窄字符(narrow characters (of type char))的标准输 ⼊流。 3…...
卡码网KamaCoder 117. 软件构建
题目来源:117. 软件构建 C题解(来源代码随想录):拓扑排序:给出一个 有向图,把这个有向图转成线性的排序。拓扑排序也是图论中判断有向无环图的常用方法。 拓扑排序的过程,其实就两步࿱…...
Acwing 线性DP
状态转移方程呈现出一种线性的递推形式的DP,我们将其称为线性DP。 Acwing 898.数字三角形 实现思路: 对这个三角形的数字进行编号,状态表示依然可以用二维表示,即f(i,j),i表示横坐标(横线),j表…...
Docker面试-24年
1、Docker 是什么? Docker一个开源的应用容器引擎,是实现容器技术的一种工具,让开发者可以打包他们的应用以及环境到一个镜像中,可以快速的发布到任何流行的操作系统上。 2、Docker的三大核心是什么? 镜像:Docker的…...
ubuntu 安装k8s
#关闭 Swap 内存,配置完成建议重启一下 nano /etc/fstab #注释下面相似的一行 #/swapfile none swap sw 0 0 #重启 reboot#部属k8s apt update && apt install -y apt-transport-https 下载 gpg 密钥 curl https://mi…...
No.4 笔记 | 探索网络安全:揭开Web世界的隐秘防线
在这个数字时代,网络安全无处不在。了解Web安全的基本知识,不仅能保护我们自己,也能帮助我们在技术上更进一步。让我们一起深入探索Web安全的世界,掌握那些必备的安全知识! 1. 客户端与WEB应用安全 前端漏洞࿱…...
spring揭秘24-springmvc02-5个重要组件
文章目录 【README】【1】HanderMapping-处理器映射容器【1.1】HanderMapping实现类【1.1.1】SimpleUrlHandlerMapping 【2】Controller(二级控制器)【2.1】AbstractController抽象控制器(控制器基类) 【3】ModelAndView(模型与视…...
关键字:register
1.铺垫 1.1 计算集中具有存储能力的硬件:cpu中的寄存器、cache,内存,硬盘等 1.2离cpu越近的存储硬件,效率越高,单价成本越贵;离cpu越远的存储硬件,效率越低,单价成本越便宜&#x…...
力扣 简单 110.平衡二叉树
文章目录 题目介绍解法 题目介绍 解法 平衡二叉树:任意节点的左子树和右子树的高度之差的绝对值不超过 1 //利用递归方法自顶向下判断以每个节点为根节点的左右子树的最大深度是否大于1 class Solution {public boolean isBalanced(TreeNode root) {if(root null){return tr…...
基于深度学习的代码优化
基于深度学习的代码优化是一种使用深度学习技术来提升编程代码性能、减少运行时间或资源消耗的方式。通过模型学习大量代码的特征和结构,深度学习可以帮助自动化地识别和应用优化策略。以下是一些关键应用领域: 编译器优化:深度学习模型可以用…...
汽车电气系统中KL30、KL15、KL50、KLR、KL31、KL87、KL75的作用
目录 1、KL30 (Battery Positive Terminal) 2、KL15 (Ignition Switch, Positive) 3、KL50 (Starter Motor Terminal) 4、KLR (Ignition-Off Draw) 5、KL31 (Ground) 6、KL87 (Relay Output) 7、KL75 (Accessory) 在汽车电气系统中,KL系列的术语起源于德国&a…...
随笔(四)——代码优化
文章目录 前言1.原本代码2.新增逻辑3.优化逻辑 前言 原逻辑:后端data数据中返回数组,数组中有两个对象,一个是属性指标,一个是应用指标,根据这两个指标展示不同的多选框 1.原本代码 getIndicatorRange(indexReportLi…...
安装管理K8S的开源项目KubeClipper介绍
安装管理K8S的开源项目KubeClipper介绍 1. 概述 KubeClipper是九州云开源的一个图形化界面 Kubernetes 多集群管理工具,旨在提供易使用、易运维、极轻量、生产级的 Kubernetes 多集群全生命周期管理服务。让运维工程师从繁复的配置和晦涩的命令行中解放出来&#…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
