demo1- 简单的静态好友列表
自己创建一个类
删除掉默认自带的MainWindows.cpp、.hpp ,并换成自己写的
示例:
这里是在给数据添加数据模型、给数据模型添加数据
FFriendListWidget::FFriendListWidget(QWidget *parent)
: QListView{parent}
{
// 1、对于视图需要添加数据模型
m_Model = new QStandardItemModel(this);
// 2、将创建出的模型,设置到视图中
this->setModel(m_Model);
//注意我们要实现的不能被编辑,因此要禁用编辑
//遇到没用过的不知道参数怎么填的,学会查手册,
this->setEditTriggers(QAbstractItemView::NoEditTriggers);
// 3、给数据模型添加数据
// 4、给数据模型添加几行数据
m_Model->appendRow(new QStandardItem("粥小欣"));
m_Model->appendRow(new QStandardItem("粥中欣"));
m_Model->appendRow(new QStandardItem("粥大欣"));
m_Model->appendRow(new QStandardItem("粥超欣"));
}
通过代理的方式相当于是自定义的,从数据模型到视图的是默认的
添加代理:
FriendListWidgetDelegate.h
继承自代理类,专门处理样式项的代理类
#include <QStyledItemDelegate>
#ifndef FFRIENDLISTWIDGETDELEGATE_H
#define FFRIENDLISTWIDGETDELEGATE_H
//继承自代理类,专门处理样式项的代理类
#include <QStyledItemDelegate>
class FFriendListWidgetDelegate: public QStyledItemDelegate
{
Q_OBJECT
public:
FFriendListWidgetDelegate(QObject* parent = nullptr);
};
#endif // FFRIENDLISTWIDGETDELEGATE_H
注:为了把我们自己创建出的类添加到对象树,在自定义类的构造函数添加基类参数
friendlistwidget.h
添加一个简单的数据模型
#include <QStandardItemModel>
#ifndef FFRIENDLISTWIDGET_H
#define FFRIENDLISTWIDGET_H
#include <QWidget>
#include <QListView>
//添加一个简单的数据模型
#include <QStandardItemModel>
//数据代理
#include "FriendListWidgetDelegate.h"
class FFriendListWidget : public QListView
{
Q_OBJECT
public:
explicit FFriendListWidget(QWidget *parent = nullptr);
signals:
private:
//声明模型
QStandardItemModel* m_Model;
FFriendListWidgetDelegate* m_Delegate;
};
#endif // FFRIENDLISTWIDGET_H
FriendListWidgetDelegate.cpp
#include "FriendListWidgetDelegate.h"
FFriendListWidgetDelegate::FFriendListWidgetDelegate(QObject* parent)
:QStyledItemDelegate(parent)
{
}
在 friendlistwidget.cpp中创建代理
m_Delegate = new FFriendListWidgetDelegate(this);
this->setItemDelegate(m_Delegate);
#include "friendlistwidget.h"
FFriendListWidget::FFriendListWidget(QWidget *parent)
: QListView{parent}
{
// 1、对于视图需要添加数据模型
m_Model = new QStandardItemModel(this);
// 2、将创建出的模型,设置到视图中
this->setModel(m_Model);
// 创建代理
m_Delegate = new FFriendListWidgetDelegate(this);
this->setItemDelegate(m_Delegate);
//注意我们要实现的不能被编辑,因此要禁用编辑
//遇到没用过的不知道参数怎么填的,学会查手册,
this->setEditTriggers(QAbstractItemView::NoEditTriggers);
// 3、给数据模型添加数据
// 4、给数据模型添加几行数据
m_Model->appendRow(new QStandardItem("粥小欣"));
m_Model->appendRow(new QStandardItem("粥中欣"));
m_Model->appendRow(new QStandardItem("粥大欣"));
m_Model->appendRow(new QStandardItem("粥超欣"));
}
数据想要显示、需要被放到代理中去全部处理一遍,最后再显示到视图上,需要将数据模型传到代理中去进行处理再显示!!
这些都是代理类中可重写的成员函数
示例:friendlistwidget.cpp
#include "friendlistwidget.h"
FFriendListWidget::FFriendListWidget(QWidget *parent)
: QListView{parent}
{
// 1、对于视图需要添加数据模型
m_Model = new QStandardItemModel(this);
// 2、将创建出的模型,设置到视图中
this->setModel(m_Model);
// 创建代理
m_Delegate = new FFriendListWidgetDelegate(this);
this->setItemDelegate(m_Delegate);
//注意我们要实现的不能被编辑,因此要禁用编辑
//遇到没用过的不知道参数怎么填的,学会查手册,
this->setEditTriggers(QAbstractItemView::NoEditTriggers);
// 3、给数据模型添加数据
// QVariant--QT中的通用类型
QStandardItem* item = new QStandardItem();
item->setData("粥小欣", Qt::UserRole + 1);
item->setData("浮生若梦,唯爱永恒", Qt::UserRole + 2);
item->setData(":/images/01.jpeg", Qt::UserRole + 3);
m_Model->appendRow(item);
item = new QStandardItem();
item->setData("粥欣欣", Qt::UserRole + 1);
item->setData("品味独特,别具一格", Qt::UserRole + 2);
item->setData(":/images/02.png", Qt::UserRole + 3);
m_Model->appendRow(item);
item = new QStandardItem();
item->setData("粥大欣", Qt::UserRole + 1);
item->setData("做一个干净洒脱的人", Qt::UserRole + 2);
item->setData(":/images/03.png", Qt::UserRole + 3);
m_Model->appendRow(item);
item = new QStandardItem();
item->setData("粥超欣", Qt::UserRole + 1);
item->setData("锣声一响,黄金万两", Qt::UserRole + 2);
item->setData(":/images/04.png", Qt::UserRole + 3);
m_Model->appendRow(item);
}
FriendListWidgetDelegate.cpp
#include "FriendListWidgetDelegate.h"
#include <QPainter>
FFriendListWidgetDelegate::FFriendListWidgetDelegate(QObject* parent)
:QStyledItemDelegate(parent)
{
}
//重写/每一项的高度
QSize FFriendListWidgetDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
// qDebug() << index;
return QSize(option.rect.width(), 60);
}
void FFriendListWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QString netName = index.data(Qt::UserRole + 1).toString();
QString signature = index.data(Qt::UserRole + 2).toString();
QString Pixmap = index.data(Qt::UserRole + 3).toString();
//绘制文本
painter->drawText(65, 25 + option.rect.y(), netName);
painter->drawText(65, 45 + option.rect.y(), signature);
//绘制图片
painter->drawPixmap(0, option.rect.y() + 5, 50, 50, QPixmap(Pixmap));
QStyledItemDelegate::paint(painter, option, index);
}
FriendListWidgetDelegate.h
#ifndef FFRIENDLISTWIDGETDELEGATE_H
#define FFRIENDLISTWIDGETDELEGATE_H
//继承自代理类,专门处理样式项的代理类
#include <QStyledItemDelegate>
#include <QDebug>
class FFriendListWidgetDelegate: public QStyledItemDelegate
{
Q_OBJECT
public:
FFriendListWidgetDelegate(QObject* parent = nullptr);
//重写/每一项的高度
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
//重写绘制
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
#endif // FFRIENDLISTWIDGETDELEGATE_H
运行结果:
在实际时生活中,一个人的好友列表是不同的,这样的数据不能写死:
读取json文件:
[
{
"netname": "粥小欣",
"signature": "浮生若梦,唯爱永恒",
"pixmap": ":/images/01.jpeg"
},
{
"netname": "粥欣欣",
"signature": "品味独特,别具一格",
"pixmap": ":/images/02.png"
},
{
"netname": "粥大欣",
"signature": "做一个干净洒脱的人",
"pixmap": ":/images/03.png"
},
{
"netname": "粥超欣",
"signature": "锣声一响,黄金万两",
"pixmap": ":/images/04.png"
}
]
动态读取数据代码:
#include "friendlistwidget.h"
#include <QFile>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
FFriendListWidget::FFriendListWidget(QWidget *parent)
: QListView{parent}
{
// 1、对于视图需要添加数据模型
m_Model = new QStandardItemModel(this);
// 2、将创建出的模型,设置到视图中
this->setModel(m_Model);
// 创建代理
m_Delegate = new FFriendListWidgetDelegate(this);
this->setItemDelegate(m_Delegate);
//注意我们要实现的不能被编辑,因此要禁用编辑
//遇到没用过的不知道参数怎么填的,学会查手册,
this->setEditTriggers(QAbstractItemView::NoEditTriggers);
// 3、给数据模型添加数据
// QVariant--QT中的通用类型
//读取 json 文件
//打开json文件
QFile jsonFile(":/json/FriendList.json");
if(jsonFile.open(QIODevice::ReadOnly)){
//成功打开,填写数据
//处理json数据
// 以数组方式读取数据-现在最外层是一个[],因此以数组方式读取,如果最外层是{},以对象方式读取
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonFile.readAll());
QJsonArray jsonArray = jsonDocument.array();
qDebug() << jsonArray;
for(const QJsonValue& object : jsonArray)
{
qDebug() << object;
QJsonObject jsonObject = object.toObject();
QStandardItem* item = new QStandardItem();
item->setData(jsonObject["netname"].toString(), Qt::UserRole + 1 );
item->setData(jsonObject["signature"].toString(), Qt::UserRole + 2);
item->setData(jsonObject["pixmap"].toString(), Qt::UserRole + 3);
m_Model->appendRow(item);
}
//处理完成,关闭文件
jsonFile.close();
}
}
点击某个好友,弹出一个聊天窗口
思路:通过点击事件,来添加窗口,我们这里使用双击事件:
doubleClicked()
测验点击事件:
槽函数:
void FFriendListWidget::ListView_DoubleClicked(const QModelIndex &index)
{
FChatWidget* chatWidget = new FChatWidget(index.data(Qt::UserRole + 1).toString()
, index.data(Qt::UserRole + 3).toString());
chatWidget->show();
qDebug() << index.data(Qt::UserRole + 1);
}
ChatWidget.h
#ifndef FCHATWIDGET_H
#define FCHATWIDGET_H
#include <QWidget>
class FChatWidget : public QWidget
{
Q_OBJECT
public:
explicit FChatWidget(QString netName, QString Pixmap, QWidget *parent = nullptr);
signals:
};
#endif // FCHATWIDGET_H
friendListWidget.cpp
#include "friendlistwidget.h"
#include <QFile>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <ChatWidget.h>
FFriendListWidget::FFriendListWidget(QWidget *parent)
: QListView{parent}
{
// 1、对于视图需要添加数据模型
m_Model = new QStandardItemModel(this);
// 2、将创建出的模型,设置到视图中
this->setModel(m_Model);
// 创建代理
m_Delegate = new FFriendListWidgetDelegate(this);
this->setItemDelegate(m_Delegate);
//注意我们要实现的不能被编辑,因此要禁用编辑
//遇到没用过的不知道参数怎么填的,学会查手册,
this->setEditTriggers(QAbstractItemView::NoEditTriggers);
// 3、给数据模型添加数据
// QVariant--QT中的通用类型
#if 0
QStandardItem* item = new QStandardItem();
item->setData("粥小欣", Qt::UserRole + 1 );
item->setData("浮生若梦,唯爱永恒", Qt::UserRole + 2);
item->setData(":/images/01.jpeg", Qt::UserRole + 3);
m_Model->appendRow(item);
item = new QStandardItem();
item->setData("粥欣欣", Qt::UserRole + 1);
item->setData("品味独特,别具一格", Qt::UserRole + 2);
item->setData(":/images/02.png", Qt::UserRole + 3);
m_Model->appendRow(item);
item = new QStandardItem();
item->setData("粥大欣", Qt::UserRole + 1);
item->setData("做一个干净洒脱的人", Qt::UserRole + 2);
item->setData(":/images/03.png", Qt::UserRole + 3);
m_Model->appendRow(item);
item = new QStandardItem();
item->setData("粥超欣", Qt::UserRole + 1);
item->setData("锣声一响,黄金万两", Qt::UserRole + 2);
item->setData(":/images/04.png", Qt::UserRole + 3);
m_Model->appendRow(item);
#endif
//读取 json 文件
//打开json文件
QFile jsonFile(":/json/FriendList.json");
if(jsonFile.open(QIODevice::ReadOnly)){
//成功打开,填写数据
//处理json数据
// 以数组方式读取数据-现在最外层是一个[],因此以数组方式读取,如果最外层是{},以对象方式读取
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonFile.readAll());
QJsonArray jsonArray = jsonDocument.array();
qDebug() << jsonArray;
for(const QJsonValue& object : jsonArray)
{
qDebug() << object;
QJsonObject jsonObject = object.toObject();
QStandardItem* item = new QStandardItem();
item->setData(jsonObject["netname"].toString(), Qt::UserRole + 1 );
item->setData(jsonObject["signature"].toString(), Qt::UserRole + 2);
item->setData(jsonObject["pixmap"].toString(), Qt::UserRole + 3);
m_Model->appendRow(item);
}
//处理完成,关闭文件
jsonFile.close();
}
connect(this, &QListView::doubleClicked, this, &FFriendListWidget::ListView_DoubleClicked);
}
void FFriendListWidget::ListView_DoubleClicked(const QModelIndex &index)
{
FChatWidget* chatWidget = new FChatWidget(index.data(Qt::UserRole + 1).toString()
, index.data(Qt::UserRole + 3).toString());
chatWidget->show();
qDebug() << index.data(Qt::UserRole + 1);
}
对话窗口可编辑:
解决办法:
在创建聊天窗口的槽函数中做一个判断
void FFriendListWidget::ListView_DoubleClicked(const QModelIndex &index) { QString netName = index.data(Qt::UserRole + 1).toString(); QString signature = index.data(Qt::UserRole + 2).toString(); QString Pixmap = index.data(Qt::UserRole + 3).toString(); // FChatWidget* chatWidget = new FChatWidget(netName, Pixmap); FChatWidget* ChatWidget = index.data(Qt::UserRole+4).value<FChatWidget*>(); if(ChatWidget == nullptr){ ChatWidget = new FChatWidget(netName, Pixmap); QVariant variant; variant.setValue(ChatWidget); m_Model->itemFromIndex(index)->setData(variant, Qt::UserRole+4); } ChatWidget->show(); // qDebug() << index.data(Qt::UserRole + 1); }
demo2
代码:
main.cpp
#include "widget.h" // 自定义窗口头文件(实际未使用) #include <QApplication> // Qt 应用程序核心类 #include <QSplitter> // 分割窗口组件 #include <QTreeView> // 树形视图组件 #include <QListView> // 列表视图组件 #include <QFileSystemModel> // 文件系统数据模型 #include <QDir> // 目录操作类 int main(int argc, char *argv[]) { QApplication a(argc, argv); // Widget w; // w.show(); QSplitter *splitter = new QSplitter; QFileSystemModel *model = new QFileSystemModel; //将当前路径设置给该模型 model->setRootPath(QDir::currentPath()); //实例化视图 QTreeView *treeView = new QTreeView(splitter); //将视图和模型绑定起来 treeView->setModel(model); QListView *listView = new QListView(splitter); listView->setModel(model); splitter->show(); return a.exec(); }
QSplitter
:可拖动的分割窗口容器
QFileSystemModel
:提供文件系统的数据模型
QDir::currentPath()
:获取应用程序启动目录监视工程当前目录:
demo3更新demo1 更加细致的MVD
Q_DECLARE_METATYPE(FriendItemData)
是 Qt 框架中的一个宏,用于注册自定义类型FriendItemData
,使其能够在 Qt 的元对象系统中进行处理,从而能够将该自定义类型存储在QVariant
中或者用于信号和槽等机制中。以下是对它的详细讲解:1. 背景知识
在 Qt 中,
QVariant
是一个通用的容器,可以存储各种基本数据类型(如int
、double
、QString
等)。然而,默认情况下,
QVariant
不支持存储自定义类型(如FriendItemData
)。为了在QVariant
或信号和槽机制中使用自定义类型,需要将它注册到 Qt 的元类型系统中。2. 宏的作用
Q_DECLARE_METATYPE(FriendItemData)
宏的作用是向 Qt 的元对象系统注册自定义类型FriendItemData
。注册后,Qt 能够识别
FriendItemData
类型,并为其分配一个唯一的类型 ID,从而可以将FriendItemData
存储在QVariant
中或者用于信号和槽的参数传递。3. 工作原理
当你使用
Q_DECLARE_METATYPE(FriendItemData)
注册类型时,Qt 的moc
(元对象编译器)会为该类型生成必要的元数据代码。这些元数据包括类型名称、类型 ID、类型转换函数等信息,使得 Qt 框架能够正确地处理该自定义类型。
4. 使用场景
存储在
QVariant
中:将FriendItemData
对象存储在QVariant
中,便于在需要时提取出来。QVariant variant; FriendItemData data; variant.setValue(data); // 存储 FriendItemData retrievedData = variant.value<FriendItemData>(); // 提取
用于信号和槽:在信号和槽中传递自定义类型参数。
class MyClass : public QObject { Q_OBJECT public: signals: void dataChanged(FriendItemData newData); };
QML 和 C++ 交互:在 C++ 和 QML 之间传递自定义类型的数据。
5. 代码示例
假设我们有一个自定义类型
FriendItemData
:struct FriendItemData { QString name; int age; QString email; };
使用
Q_DECLARE_METATYPE
注册它:Q_DECLARE_METATYPE(FriendItemData)
然后可以将其存储在
QVariant
中:FriendItemData data; data.name = "Alice"; data.age = 25; data.email = "alice@example.com"; QVariant variant; variant.setValue(data); // 提取数据 FriendItemData retrievedData = variant.value<FriendItemData>(); qDebug() << retrievedData.name; // 输出 "Alice"
需要知道的理论知识:
1.基本概念
在 Qt 的模型 - 视图框架中,数据通常由模型(Model)进行管理,视图(View)负责展示这些数据。
QModelIndex
就像是一个 “定位符” 或者 “指针”,用来唯一标识模型中的一个特定数据项。它不仅仅是一个简单的行号或列号,还可能包含其他信息,比如父项的索引(在树形结构的模型中尤为重要),从而能够准确地定位到模型中的任何一个数据项。
2. 主要用途
定位数据项 :在模型中,每个数据项都有一个对应的
QModelIndex
。视图通过这个索引来请求模型中的数据进行展示。例如,在一个表格视图中,用户点击某个单元格,视图会通过该单元格对应的QModelIndex
来获取单元格中的数据并进行相应操作。数据交互操作 :当需要对模型中的数据进行插入、删除、修改等操作时,通常也需要使用
QModelIndex
来指定要操作的数据项的位置。比如,在一个文件系统模型中,要删除一个文件,就需要先获取该文件对应的QModelIndex
,然后通过模型的接口进行删除操作。传递数据项信息 :在信号和槽机制中,
QModelIndex
可以作为参数在不同的组件之间传递数据项的位置信息。例如,当某个数据项的状态发生变化时,模型可以发出一个信号,将该数据项的QModelIndex
传递给槽函数,以便槽函数能够根据索引对数据项进行进一步的处理。3. 详细结构
行(row) :表示数据项在父项的子项列表中的行位置。在表格模型中,它类似于表格的行号;在树形模型中,它表示子节点在父节点的子节点列表中的位置。
列(column) :表示数据项的列位置,在表格模型中比较常见,比如一个多列表格模型中,每个数据项有对应的列号。在树形模型中,也可以根据需要定义列的概念。
父项索引(parent index) :这是
QModelIndex
的重要组成部分,尤其对于具有层次结构(例如树形结构)的模型。如果一个数据项是某个父项的子项,那么它的父项索引就指向该父项的QModelIndex
。如果数据项是模型的顶层项,则其父项索引是一个无效的QModelIndex
(通常通过QModelIndex()
表示)。4. 使用示例
假设有一个表格模型
QStandardItemModel
,我们可以使用QModelIndex
来获取和设置单元格的数据:在树形模型中,
QModelIndex
的父项索引用于表示树的层次结构:QTreeView *treeView = new QTreeView; QStandardItemModel *model = new QStandardItemModel(); treeView->setModel(model); // 添加根节点 QStandardItem *rootItem = model->invisibleRootItem(); QStandardItem *parentItem = new QStandardItem("Parent"); rootItem->appendRow(parentItem); // 添加子节点 QStandardItem *childItem = new QStandardItem("Child"); parentItem->appendRow(childItem); // 获取子节点的索引 QModelIndex parentIndex = parentItem->index(); QModelIndex childIndex = childItem->index(); // 子节点的父项索引就是父节点的索引 QModelIndex childParentIndex = childIndex.parent(); // 应该等于 parentIndex
C++ 中的 static constexpr
成员变量
static
关键字
static
成员变量属于类本身,而不是类的某个对象。所有对象共享同一个static
成员变量。例如,对于一个类
MyClass
,它的static
成员变量staticVar
只会在内存中存在一份。
constexpr
关键字
constexpr
表示这个变量是一个编译时常量。它的值在编译时期就被确定下来,并且可以用于需要常量表达式的地方。编译时常量的值必须在编译时就能计算出来,所以它需要一个在编译时就能确定的初始值。
为什么可以在类内进行初始化?
编译时常量的要求 :因为
ITEM_HEIGHT
被声明为constexpr
,其值必须在编译时就被确定。C++ 允许在类内直接初始化这样的成员变量,这样可以提高代码的可读性和简洁性。不需要动态内存分配或运行时计算 :对于
static constexpr
变量,编译器可以将其值直接内联到代码中,不需要在运行时进行内存分配或计算。与普通
static
成员变量的区别对于普通的
static
成员变量,它需要在类外进行定义。例如:class MyClass { public: static int staticVar; }; int MyClass::staticVar = 0; // 类外定义
这是因为普通的
static
成员变量需要在内存中分配空间,而这个空间的大小和初始化方式可能依赖于运行时环境。但是,
static constexpr
成员变量由于其值在编译时就能确定,并且不需要动态分配内存或复杂的初始化过程,所以可以在类内直接进行初始化。编译器会处理这个值,使其在需要的地方直接以常量的形式出现。
1. 函数作用
这个函数的作用是返回一个
QSize
对象,该对象指定了委托(Delegate)所表示的数据项在视图中推荐的大小。sizeHint
是 Qt 框架中委托类(QAbstractItemDelegate
及其子类)的一个重要成员函数,它用于告诉视图每个数据项应该占用多大的空间。2. 函数参数
const QStyleOptionViewItem &option
:
这是一个引用参数,类型为
QStyleOptionViewItem
,它包含了视图项的样式选项。这些选项提供了用于绘制和计算大小的各种信息,例如视图项的矩形区域(rect
)、显示状态(如是否选中、是否启用等)。在这个函数中,主要用到了
option.rect.width()
来获取视图项的宽度。
const QModelIndex &index
:
这是一个引用参数,类型为
QModelIndex
,它代表了模型中的一个数据项。通过这个索引,可以访问模型中对应的数据项的信息。在这个函数中,可能没有直接使用
index
(代码片段中未体现),但在更复杂的场景下,可以根据index
来获取不同的大小提示,例如根据不同的数据项类型或状态返回不同的高度。3. 函数返回值
QSize
是一个类,用于表示二维大小(宽度和高度)。在这段代码中,返回的宽度是
option.rect.width()
,即视图项的可用宽度。高度是
ITEM_HEIGHT
,这是一个常量,表示每个数据项的高度固定为 80 像素。4. 代码的逻辑和含义
设置宽度 :宽度被设置为
option.rect.width()
,这意味着视图项的宽度将与视图中为该数据项分配的区域宽度一致。这种设置通常用于让数据项占据整个可用宽度,尤其是在列表视图或表格视图中。设置高度 :高度被设置为
ITEM_HEIGHT
,这是一个固定的常量值。这种设置意味着不管数据项的实际内容如何,它的高度都被固定为 80 像素。这种固定高度的设置在一些应用场景中很有用,例如在一个联系人列表中,每个联系人条目都占用相同的高度,以保持视图的整齐和一致性。
代码:可以直接查看我的gitee
MyModelView3 · 粥欣睿/qt学习与练习 - 码云 - 开源中国
结语:
随着这篇博客接近尾声,我衷心希望我所分享的内容能为你带来一些启发和帮助。学习和理解的过程往往充满挑战,但正是这些挑战让我们不断成长和进步。我在准备这篇文章时,也深刻体会到了学习与分享的乐趣。
在此,我要特别感谢每一位阅读到这里的你。是你的关注和支持,给予了我持续写作和分享的动力。我深知,无论我在某个领域有多少见解,都离不开大家的鼓励与指正。因此,如果你在阅读过程中有任何疑问、建议或是发现了文章中的不足之处,都欢迎你慷慨赐教。
你的每一条反馈都是我前进路上的宝贵财富。同时,我也非常期待能够得到你的点赞、收藏,关注这将是对我莫大的支持和鼓励。当然,我更期待的是能够持续为你带来有价值的内容。