Qt xml示范

news2024/12/26 9:20:44

1.数据格式

#ifndef XML_DATA_H
#define XML_DATA_H

#include<QWidget>

struct Student
{
    int s_id;
    QString s_name;
    double s_math_score;
    double s_english_score;

};
struct Teacher{
    int t_id;
    QString t_name;
    QVector<Student> t_students_v;
};




#endif // XML_DATA_H

2.xml示范

2.1 .h文件

#ifndef XML_EXAMPLE1_H
#define XML_EXAMPLE1_H

#include <QObject>
#include"XML_Data.h"
#include <QtXml>
#include <QString>
#include <QDebug>
#include"tinyxml2.h"

class Xml_Example1 : public QObject
{
    Q_OBJECT
public:
    explicit Xml_Example1(QObject *parent = nullptr);

    void saveXml_doc(const Student& stu,const QString& filePath);
    void saveXml_writer(const Student& stu,const QString& filePath);
    void saveXml_tinyxml2(const Student& stu,const QString& filePath);

    void saveXml_doc(const Teacher& tea,const QString& filePath);
    void saveXml_writer(const Teacher& tea,const QString& filePath);
    void saveXml_tinyxml2(const Teacher& tea,const QString& filePath);

    void loadXml_doc(Student& stu,const QString& filePath);
    void loadXml_tinyxml2(Student& stu,const QString& filePath);

    void loadXml_doc(Teacher& tea,const QString& filePath);
    void loadXml_tinyxml2(Teacher& tea,const QString& filePath);


signals:
};

#endif // XML_EXAMPLE1_H

2.2 .cpp文件

#include "xml_example1.h"

Xml_Example1::Xml_Example1(QObject *parent)
    : QObject{parent}
{}

void Xml_Example1::saveXml_doc(const Student &stu, const QString &filePath)
{
    QDomDocument doc;
    // 创建根节点
    QDomElement root = doc.createElement("Student");
    doc.appendChild(root);

    // 创建子节点并设置属性
    QDomElement id = doc.createElement("ID");
    id.appendChild(doc.createTextNode(QString::number(stu.s_id)));
    root.appendChild(id);

    QDomElement name = doc.createElement("Name");
    name.appendChild(doc.createTextNode(stu.s_name));
    root.appendChild(name);

    QDomElement math_score = doc.createElement("MathScore");
    math_score.appendChild(doc.createTextNode(QString::number(stu.s_math_score)));
    root.appendChild(math_score);

    QDomElement english_score = doc.createElement("EnglishScore");
    english_score.appendChild(doc.createTextNode(QString::number(stu.s_english_score)));
    root.appendChild(english_score);

    // 保存到文件
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qDebug() << "Failed to open file for writing.";
        return;
    }

    QTextStream out(&file);
    // out.setCodec("UTF-8");
    doc.save(out, 4);
    file.close();
}

void Xml_Example1::saveXml_writer(const Student &stu, const QString &filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qDebug() << "Failed to open file for writing.";
        return;
    }
    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true); // 设置自动格式化,使XML文档更易读

    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("Student");

    xmlWriter.writeTextElement("ID", QString::number(stu.s_id));
    xmlWriter.writeTextElement("Name", stu.s_name);
    xmlWriter.writeTextElement("MathScore", QString::number(stu.s_math_score));
    xmlWriter.writeTextElement("EnglishScore", QString::number(stu.s_english_score));

    xmlWriter.writeEndElement(); // 结束Student节点
    xmlWriter.writeEndDocument();

    file.close();
}

void Xml_Example1::saveXml_tinyxml2(const Student &stu, const QString &filePath)
{
    // 创建一个 XML 文档对象
    tinyxml2::XMLDocument doc;

    // 创建根节点
    tinyxml2::XMLElement* root = doc.NewElement("Student");
    doc.InsertEndChild(root);

    // 添加学生信息作为子节点
    tinyxml2::XMLElement* idElement = doc.NewElement("ID");
    idElement->SetText(stu.s_id);
    root->InsertEndChild(idElement);

    tinyxml2::XMLElement* nameElement = doc.NewElement("Name");
    nameElement->SetText(stu.s_name.toStdString().c_str());
    root->InsertEndChild(nameElement);

    tinyxml2::XMLElement* mathScoreElement = doc.NewElement("MathScore");
    mathScoreElement->SetText(stu.s_math_score);
    root->InsertEndChild(mathScoreElement);

    tinyxml2::XMLElement* englishScoreElement = doc.NewElement("EnglishScore");
    englishScoreElement->SetText(stu.s_english_score);
    root->InsertEndChild(englishScoreElement);

    // 保存 XML 文档到文件
    doc.SaveFile(filePath.toStdString().c_str());

}

void Xml_Example1::saveXml_doc(const Teacher &tea, const QString &filePath)
{
    // 创建 QDomDocument 对象
    QDomDocument doc;

    // 创建根元素 <Teacher>
    QDomElement root = doc.createElement("Teacher");
    doc.appendChild(root);

    // 创建子元素 <ID> 和 <Name>,并添加到 <Teacher> 中
    QDomElement idElement = doc.createElement("ID");
    QDomText idText = doc.createTextNode(QString::number(tea.t_id));
    idElement.appendChild(idText);
    root.appendChild(idElement);

    QDomElement nameElement = doc.createElement("Name");
    QDomText nameText = doc.createTextNode(tea.t_name);
    nameElement.appendChild(nameText);
    root.appendChild(nameElement);

    // 创建子元素 <Student>,并添加到 <Teacher> 中
    for (const auto &stu : tea.t_students_v)
    {
        QDomElement studentElement = doc.createElement("Student");

        QDomElement stuIdElement = doc.createElement("ID");
        QDomText stuIdText = doc.createTextNode(QString::number(stu.s_id));
        stuIdElement.appendChild(stuIdText);
        studentElement.appendChild(stuIdElement);

        QDomElement stuNameElement = doc.createElement("Name");
        QDomText stuNameText = doc.createTextNode(stu.s_name);
        stuNameElement.appendChild(stuNameText);
        studentElement.appendChild(stuNameElement);

        QDomElement mathScoreElement = doc.createElement("MathScore");
        QDomText mathScoreText = doc.createTextNode(QString::number(stu.s_math_score));
        mathScoreElement.appendChild(mathScoreText);
        studentElement.appendChild(mathScoreElement);

        QDomElement englishScoreElement = doc.createElement("EnglishScore");
        QDomText englishScoreText = doc.createTextNode(QString::number(stu.s_english_score));
        englishScoreElement.appendChild(englishScoreText);
        studentElement.appendChild(englishScoreElement);

        root.appendChild(studentElement);
    }

    // 将 QDomDocument 写入文件
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        qDebug() << "无法打开文件" << filePath;
        return;
    }
    QTextStream out(&file);
    // out.setCodec("UTF-8");
    doc.save(out, 4); // 缩进格式为4
    file.close();

}

void Xml_Example1::saveXml_writer(const Teacher &tea, const QString &filePath)
{
    // 创建文件对象
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        qDebug() << "无法打开文件" << filePath;
        return;
    }

    // 创建 XML 写入器
    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true); // 设置自动格式化,便于阅读

    // 开始写入 XML
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("Teacher");

    // 写入教师信息
    xmlWriter.writeTextElement("ID", QString::number(tea.t_id));
    xmlWriter.writeTextElement("Name", tea.t_name);

    // 写入学生信息
    for (const auto &stu : tea.t_students_v)
    {
        xmlWriter.writeStartElement("Student");
        xmlWriter.writeTextElement("ID", QString::number(stu.s_id));
        xmlWriter.writeTextElement("Name", stu.s_name);
        xmlWriter.writeTextElement("MathScore", QString::number(stu.s_math_score));
        xmlWriter.writeTextElement("EnglishScore", QString::number(stu.s_english_score));
        xmlWriter.writeEndElement(); // 关闭<Student>节点
    }

    // 结束写入 XML
    xmlWriter.writeEndElement(); // 关闭<Teacher>节点
    xmlWriter.writeEndDocument();

    // 关闭文件
    file.close();
}

void Xml_Example1::saveXml_tinyxml2(const Teacher &tea, const QString &filePath)
{
    // 创建一个 XML 文档对象
    tinyxml2::XMLDocument doc;

    // 创建根节点
    tinyxml2::XMLElement *root = doc.NewElement("Teacher");
    doc.InsertEndChild(root);

    // 添加教师信息作为子节点
    tinyxml2::XMLElement *idElement = doc.NewElement("ID");
    idElement->SetText(tea.t_id);
    root->InsertEndChild(idElement);

    tinyxml2::XMLElement *nameElement = doc.NewElement("Name");
    nameElement->SetText(tea.t_name.toStdString().c_str());
    root->InsertEndChild(nameElement);

    // 添加学生信息作为子节点
    for (const auto &stu : tea.t_students_v)
    {
        tinyxml2::XMLElement *studentElement = doc.NewElement("Student");
        root->InsertEndChild(studentElement);

        tinyxml2::XMLElement *idElement = doc.NewElement("ID");
        idElement->SetText(stu.s_id);
        studentElement->InsertEndChild(idElement);

        tinyxml2::XMLElement *nameElement = doc.NewElement("Name");
        nameElement->SetText(stu.s_name.toStdString().c_str());
        studentElement->InsertEndChild(nameElement);

        tinyxml2::XMLElement *mathScoreElement = doc.NewElement("MathScore");
        mathScoreElement->SetText(stu.s_math_score);
        studentElement->InsertEndChild(mathScoreElement);

        tinyxml2::XMLElement *englishScoreElement = doc.NewElement("EnglishScore");
        englishScoreElement->SetText(stu.s_english_score);
        studentElement->InsertEndChild(englishScoreElement);
    }

    // 保存 XML 文档到文件
    doc.SaveFile(filePath.toStdString().c_str());
}

void Xml_Example1::loadXml_doc(Student &stu, const QString &filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        // 文件无法打开
        qDebug()<<"文件无法打开";
        return;
    }

    QDomDocument xml_doc;
    if (!xml_doc.setContent(&file))
    {
        // XML 解析失败
        qDebug()<<"XML 解析失败";
        file.close();
        return;
    }

    QDomElement root = xml_doc.documentElement();
    stu.s_id = root.firstChildElement("ID").text().toInt();
    stu.s_name = root.firstChildElement("Name").text();
    stu.s_math_score = root.firstChildElement("MathScore").text().toDouble();
    stu.s_english_score = root.firstChildElement("EnglishScore").text().toDouble();

    file.close();
}

void Xml_Example1::loadXml_tinyxml2(Student &stu, const QString &filePath)
{
    // 创建一个 XML 文档对象
    tinyxml2::XMLDocument doc;

    // 加载 XML 文件
    if(doc.LoadFile(filePath.toStdString().c_str()) != tinyxml2::XML_SUCCESS) {
        qDebug() << "Error loading XML file.";
        return;
    }

    // 获取根节点
    tinyxml2::XMLElement* root = doc.FirstChildElement("Student");
    if(!root) {
        qDebug() << "Root element 'Student' not found.";
        return;
    }

    // 解析子节点并填充到Student对象
    stu.s_id = root->FirstChildElement("ID")->IntText();
    const char* name = root->FirstChildElement("Name")->GetText();
    stu.s_name = QString(name);

    stu.s_math_score = root->FirstChildElement("MathScore")->IntText();
    stu.s_english_score = root->FirstChildElement("EnglishScore")->IntText();

}

void Xml_Example1::loadXml_doc(Teacher &tea, const QString &filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        // 文件无法打开
        qDebug()<<"文件无法打开";
        return;
    }

    QDomDocument xml_doc;
    if (!xml_doc.setContent(&file))
    {
        // XML 解析失败
        qDebug()<<"XML 解析失败";
        file.close();
        return;
    }
    QDomElement root = xml_doc.documentElement();
    tea.t_id=root.firstChildElement("ID").text().toInt();
    tea.t_name=root.firstChildElement("Name").text();

    QDomNodeList studentList = root.elementsByTagName("Student");
    for(int i=0; i<studentList.count(); i++)
    {
        QDomElement studentElement = studentList.at(i).toElement();
        Student student;
        student.s_id=(studentElement.firstChildElement("ID").text().toInt());
        student.s_name=(studentElement.firstChildElement("Name").text());
        student.s_math_score=(studentElement.firstChildElement("MathScore").text().toDouble());
        student.s_english_score=(studentElement.firstChildElement("EnglishScore").text().toDouble());

        // 将学生对象添加到教师对象中
        tea.t_students_v.append(student);
    }

}

void Xml_Example1::loadXml_tinyxml2(Teacher &tea, const QString &filePath)
{
    // 创建一个 XML 文档对象
    tinyxml2::XMLDocument doc;

    // 加载 XML 文件
    if(doc.LoadFile(filePath.toStdString().c_str()) != tinyxml2::XML_SUCCESS) {
        qDebug() << "Error loading XML file.";
        return;
    }

    // 获取根节点
    tinyxml2::XMLElement* root = doc.FirstChildElement("Teacher");
    if(!root) {
        qDebug() << "Root element 'Teacher' not found.";
        return;
    }

    // 解析子节点并填充到Teacher对象
    tea.t_id = root->FirstChildElement("ID")->IntText();
    tea.t_name = QString(root->FirstChildElement("Name")->GetText());

    // 读取每个学生的信息
    for(tinyxml2::XMLElement* student = root->FirstChildElement("Student"); student; student = student->NextSiblingElement("Student")) {

        Student s;

        // 解析学生的ID, Name, MathScore, 和 EnglishScore
        student->FirstChildElement("ID")->QueryIntText(&s.s_id);
        s.s_name = student->FirstChildElement("Name")->GetText();
        student->FirstChildElement("MathScore")->QueryDoubleText(&s.s_math_score);
        student->FirstChildElement("EnglishScore")->QueryDoubleText(&s.s_english_score);

        tea.t_students_v.append(s);
        // 将学生信息存储起来,这里的处理方式取决于具体的Teacher和Student的定义
        // 此处假设Teacher类和Student类已经定义,且有适当的方法来存储这些信息

    }


    // 获取学生节点
    // tinyxml2::XMLElement* studentElement = root->FirstChildElement("Students");
    // if(!studentElement) {
    //     qDebug() << "Element 'Students' not found.";
    //     return;
    // }

    // tinyxml2::XMLNode* studetsNode=root->

    // 解析学生节点
    // for(tinyxml2::XMLElement* studentNode = studentElement->FirstChildElement("Student");
    //      studentNode;
    //      studentNode = studentNode->NextSiblingElement("Student")) {

    //     Student stu;
    //     stu.s_id = studentNode->FirstChildElement("ID")->IntText();
    //     stu.s_name = QString(studentNode->FirstChildElement("Name")->GetText());
    //     stu.s_math_score = studentNode->FirstChildElement("MathScore")->DoubleText();
    //     stu.s_english_score = studentNode->FirstChildElement("EnglishScore")->DoubleText();

    //     // 将学生添加到老师的学生列表中
    //     tea.t_students_v.push_back(stu);
    // }
}

3.测试

#include "widget.h"

#include <QApplication>
#include"xml_example1.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    Xml_Example1 x_e;
    Student stu;
    stu.s_id = 1;
    stu.s_name = "张三";
    stu.s_math_score = 90.5;
    stu.s_english_score = 85.3;

    Student stu2;
    stu2.s_id = 1;
    stu2.s_name = "张埃里克";
    stu2.s_math_score = 90.5;
    stu2.s_english_score = 85.3;


    Teacher t;
    t.t_id=11;
    t.t_name="tea";
    t.t_students_v.append(stu);
    t.t_students_v.append(stu2);

    x_e.saveXml_doc(stu, "student_doc.xml");
    x_e.saveXml_writer(stu, "student_writer.xml");
    x_e.saveXml_tinyxml2(stu, "student_tinyxml2.xml");

    x_e.saveXml_doc(t, "teacher_doc.xml");
    x_e.saveXml_writer(t, "teacher_writer.xml");
    x_e.saveXml_tinyxml2(t, "teacher_tinyxml2.xml");

    Student s3;
    // x_e.loadXml_doc(s3,"student_doc.xml");
    x_e.loadXml_tinyxml2(s3,"student_tinyxml2.xml");
    // qDebug()<<s3.s_name<<s3.s_english_score<<s3.s_math_score<<s3.s_id;

    Teacher t3;
    x_e.loadXml_doc(t3,"teacher_tinyxml2.xml");
    qDebug()<<t3.t_id<<t3.t_name<<t3.t_students_v.size();
    return a.exec();
}

4.效果图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1624834.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文解读:(VPT)Visual Prompt Tuning

文章汇总 要解决的问题 大型模型应用于下游任务本身就存在挑战。最明显的(通常也是最有效的)适应策略是对预先训练好的模型进行全面的端到端微调。 动机 只微调参数的一个子集 解决的办法 只在输入空间中引入少量特定于任务的可学习参数&#xff0c;而在下游训练期间冻结…

STM32的GPIO控制寄存器开发

寄存器GPIO控制 寄存器地址 寄存器地址计算 某个寄存器地址&#xff0c;由三个参数决定&#xff1a;1、总线基地址&#xff08;BUS_BASE_ADDR&#xff09;&#xff1b;2&#xff0c;外设基于总线基地址的偏移量&#xff08;PERIPH_OFFSET&#xff09;&#xff1b;3&#xff…

书生·浦语 大模型(学习笔记-8)Lagent AgentLego 智能体应用搭建

目录 一、智能体出现的原因 二、智能体的定义 三、智能体的组成 四、Lagent 五、AgentLego 六、实战一&#xff08;Lagent&#xff09; 环境配置及安装 安装依赖 准备 Tutorial Lagent Web Demo AgentLego 使用 图片推理&#xff08;结果&#xff09;&#xff1a; …

C#基础之函数基础

函数 文章目录 1、函数基础1、概念2、函数位置3、基本语法4、实际运用5、return 2、ref 和 out1、ref 和 out 使用2、区别思考 登录 3、变长参数和参数默认值1、变长参数2、参数默认值 4、函数重载5、递归函数思考1 阶乘思考2 阶乘相加思考3 竹竿减半思考4 递归循环输出 1、函数…

diskMirror-backEnd-spring-boot | diskMirror 后端服务器 SpringBoot 版本!

diskMirror-backEnd-spring-boot diskMirror 后端服务器的 SpringBoot 版本&#xff0c;此版本中拓展了 DiskMirrorBackEnd&#xff0c;是一个完全的SpringBoot项目&#xff01; 目录 文章目录 diskMirror-backEnd-spring-boot目录我如何部署与配置docker 方式部署 diskMirro…

【树莓派】yolov5 Lite,目标检测,行人检测入侵报警

延续之前的程序&#xff1a; https://qq742971636.blog.csdn.net/article/details/138172400 文章目录 播放声音pygame不出声音怎么办&#xff08;调节音量&#xff09;树莓派上的音乐播放器&#xff08;可选&#xff09;命令行直接放歌&#xff08;尝试放mp3歌曲&#xff09; …

分类算法——模型评估(八)

1混淆矩阵 在分类任务下&#xff0c;预测结果与正确标记之间存在四种不同的组合&#xff0c;构成混淆矩阵&#xff08;适用于多分类&#xff09; TP True Possitive FN False Negative 2精确率&#xff08;Precision&#xff09;与召回率&#xff08;Recall&#xff09; 精…

第11章 Android特色开发——基于位置的服务

第11章 Android特色开发——基于位置的服务 本章中&#xff0c;将要学习一些全新的Android技术&#xff0c;这些技术有别于传统的PC或Web领域的应用技术&#xff0c;是只有在移动设备上才能实现的。 基于位置的服务&#xff08;Location Based Service&#xff09;。由于移动…

智能穿戴终端设备安卓主板方案_MTK平台智能手表PCBA定制开发

新移科技智能手表方案兼容WiFi、BLE、2~5G等多种通信能力。支持多个功能模块&#xff0c;包括&#xff1a;通话、计步、定位、睡眠监测、心率监测、血氧监测等。智能手表通过滑动与功能性按键提供高度直观的体验感受&#xff0c;从腕间即可掌控日常生活。形态支持定制包括&…

数据结构篇其二---单链表(C语言+超万字解析)

目录 前言&#xff1a; 一、顺序表的缺点和链表的引入。 二、链表概述 实现一个简单的链表 空链表的概念 三、链表的功能实现 链表的打印 链表节点的创建 链表的头插&#xff08;自上而下看完分析&#xff0c;相信你会有所收获&#xff09; 头插的前置分析 传值调用和…

【韩国】UE5的MetaHuman确实可以导入Blender进行编辑。

UE5的MetaHuman确实可以导入Blender进行编辑。根据网络上的信息&#xff0c;你可以将MetaHuman模型导出为FBX文件&#xff0c;然后在Blender中进行修改。修改完成后&#xff0c;你可以将其重新导入到Unreal Engine 5中4。请注意&#xff0c;当你在Blender中编辑模型时&#xff…

debian配置四叶草输入法

效果展示 一、前言 在linux下体验比较好的输入法只有两款&#xff1a;搜狗输入法、四叶草输入法。 ubuntu下可以成功配置搜狗输入法&#xff0c;但debian下从来没有成功过。 今天在用fcitx5 四叶草时发现VNC远程输入法会失灵&#xff0c;于是改用了ibus 四叶草&#xff0c…

Java | 冒泡排序算法实现

大家可以关注一下专栏&#xff0c;方便大家需要的时候直接查找&#xff0c;专栏将持续更新~ 题目描述 编写一个Java程序&#xff0c;实现冒泡排序算法。程序需要能够接收一个整型数组作为输入&#xff0c;并输出排序后的数组。 冒泡排序是一种简单的排序算法&#xff0c;它…

详解23种设计模式——工厂模式

工厂模式 | CoderMast编程桅杆工厂模式 设计思想 工厂模式是最常用的设计模式之一&#xff0c;属于创建型模式&#xff0c;将创建对象的权利交给了一个工厂类&#xff0c;从而提供了一种不使用构造方法的情况下创建对象的途径&#xff0c;无需指定要创建的具体类&#xff0c;将…

【可下载】CDA 1级教材《精益业务数据分析》2023最新版

CDA一级认证教材&#xff1a;《精益业务数据分析》 全面、系统地讲述业务描述性分析为企业决策行为创造价值的全流程技能&#xff0c;涵盖描述性数据分析方法、业务分析方法、数据分析结果应用方法等内容。 条理清晰的结构、通俗易懂的语言、完整立体的知识框架为读者铺开一幅…

word添加行号

打开页面设置&#xff0c;找到行号

制造型企业 如何实现便捷的机台文件统一管理?

机台文件统一管理&#xff0c;这是生产制造型企业都需要去做的&#xff0c;机台文件需要统一管理的原因主要包括以下几点&#xff1a; 1、提高效率&#xff1a;统一管理可以简化文件的访问和使用过程&#xff0c;提高工作效率&#xff0c;尤其是在需要频繁访问或更新机台文件的…

数据库MySQL的初级基础操作

文章目录 1. 介绍2. 数据库相关概念3. 启动4. 数据模型5. SQL6. DDL数据库DDL-表操作DDL-表操作-数据类型DDL-表操作-修改DDL-表操作-删除 7. 图形化界面工具DataGrip8. DML(数据操作语言)DML-添加数据DML-修改数据 9. DQL&#xff08;数据查询语言&#xff09;基本查询条件查询…

如何把经验变成可以销售的“知识产品”?

知识付费&#xff0c;很多人想做&#xff0c;但是不知道如何把自己在某方面的“经验”&#xff0c;变成一个“知识产品”&#xff0c;那么这篇文章&#xff0c;我们就来聊聊如何从0打造一个知识产品 非常简单&#xff0c;一共六个步骤&#xff1a; 第一步&#xff1a;取名字&…

【安卓13-Framework】SystemUI定制之屏蔽下拉状态栏部分快捷按钮

1、需求 屏蔽下拉状态栏谷歌录屏、省电模式、二维码扫描器等快捷按钮。 2、修改路径 普及&#xff1a;安卓的SystemUI包提供了状态栏、导航栏、通知中心等重要的用户界面元素。 状态栏小部件UI显示修改路径&#xff1a;frameworks/base/packages/SystemUI/src/com/android/s…