【Qt-数据库】
Qt编程指南
- ■ SQLite
- ■ CSV
- ■ JSON
■ SQLite
Qt 提供了很多操作数据库的类,
SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于 250KiB。 SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。就像其他数据库, SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。 SQLite 可以直接访问其存储文件。
QSqlDatabase 类用于建立数据库的连接,往往以指定加载的数据库驱动,然后设置数据库的登录参数,如主机地址,用户名、登录密码等。这些都是服务器类型的数据库所需要做的操作
在 QSqlDatabase 连接数据库后,用 QSqlTableModel 从数据库里读取出表格模型,然后通过 Qt 的 QTableView 类显示数据库的内容在我们面前。
/*需要添加模块*/
QT += sql/* 查看本机可用的数据库驱动 */
QStringList drivers = QSqlDatabase::drivers();
foreach(QString driver, drivers) {qDebug()<<driver;
}/* 以QSQLITE驱动方式打开或者创建数据库 */
sqlDatabase = QSqlDatabase::addDatabase("QSQLITE");
sqlDatabase.setDatabaseName("alarm.db");
/* 以open的方式打开alarm.db数据库,则会创建一个alarm.db */
if (!sqlDatabase.open())qDebug()<<"连接数据库错误"<<sqlDatabase.lastError()<<endl;
elseqDebug()<<"连接数据库成功"<<endl;QSqlQuery query(sqlDatabase);/* 使用指令式创建表 */
query.exec("create table alarm (id int primary key, time vchar(15), flag vchar(5))"); // primary 说明id不能为空
/* 以指令的方式插入数据 */
//query.exec("insert into alarm values(0, '06:00', 'false')");model = new QSqlTableModel(this, sqlDatabase);
/* 模型设置表的名字,需要与数据库的表的名字相同 */
model->setTable("alarm");/* 如果有修改则同步修改到数据库,* 注意这个规则需要与tabview这样的控件才生效,* 因为tabview可以直接编辑表里的内容 */
model->setEditStrategy(QSqlTableModel::OnFieldChange);
/* 成功则返回true,查看数据库里是否有alarm这个表格 */
model->select();/* 如果数据表数据为空,则添加两个闹钟 */
if (model->rowCount() == 0) {/* 插入一行 */model->insertRow(model->rowCount());/* 在该行插入数据 */model->setData(model->index(0, 0), 1);model->setData(model->index(0, 1), "06:00");model->setData(model->index(0, 2), "false");/* 插入数据后记得提交 */model->submit();/* 再插入一行 */model->insertRow(model->rowCount());model->setData(model->index(1, 0), 2);model->setData(model->index(1, 1), "18:00");model->setData(model->index(1, 2), "true");/* 提交 */model->submit();
}/* 打印出闹钟数据库里的信息 */
for (int i = 0; i < model->rowCount(); i++) {for (int j = 0; j < 3; j++) {QModelIndex qindex = model->index(i, j);switch (j) {case 0:qDebug()<<"第"<< model->data(qindex).toInt()<<"行数据";break;case 1:listWidget->addItem(model->data(qindex).toString());qDebug()<<"闹钟时间为:"<< model->data(qindex).toString();break;case 2:qDebug()<<"闹钟状态为:" << model->data(qindex).toString()<<endl;if (model->data(qindex).toString() != "true")listWidget->item(i)->setTextColor(QColor(22, 22, 22, 60));elselistWidget->item(i)->setTextColor(QColor(22, 22, 22, 225));break;default:break;}}
}/* 获取数据库里的闹钟开关状态 */
QModelIndex qindex = model->index(i, 2);
bool sw = model->data(qindex).toBool()/*设置数据库里的闹钟开关状态 */
QModelIndex qindex = model->index(i, 2);
model->setData(qindex, "true");
■ CSV
逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),
■ JSON
QJsonValue
void remove(const QString &key);
QJsonValue take(const QString &key);
bool contains(const QString &key) const;
void remove(QStringView key);
void remove(QLatin1String key);
QJsonValue take(QStringView key);
QJsonValue take(QLatin1String key);
bool contains(QStringView key) const;
bool contains(QLatin1String key) const;QJsonArray
删除数组 i;
void removeAt(int i); //jArray.removeAt(0); //ok //删除第0项
QJsonValue takeAt(int i); //qDebug() << jArray.takeAt(0).toInt() << endl; //删除第0项并返回值
替换:
QJsonArray jArray= configJson->RootObj().value("IP").toArray();
jArray.insert(3,jArray); //ok
jArray.replace(3,jArray); //ok
jArray[4]= 12; //无效 数组越界无效
jArray[0]= 54; //ok
(*configJson->RootObjPointer())["IP"]=jArray; //获取指针方式修改“IP”
configJson->savejsonfile();
QJsonObject
是否包含
是否包含Student
QJsonObject obj=doc.object();
if(obj.contains("Student"))
{
}/*创建对象并转换成QByteArray*/
QJsonObject rootobj;
rootobj["sn"] = 20001;
rootobj["type"] = "hub";
QJsonDocument jsonDoc(rootobj);
QByteArray byte=jsonDoc.toJson(); //按照json风格生成字符串,自动缩进,有空格和\n \t ; 数据量大
QByteArray byte=jsonDoc.toJson(QJsonDocument::Compact);//传入参数获取压缩后的序列化结果,紧凑格式,直接生成一堆字符串,但是占用控件小/*QByteArray转换成QJsonDocument,并得到数据*/
QJsonDocument jsonDoc1 = QJsonDocument::fromJson(byte); //QByteArray转换成文档对象
QJsonObject obj1 = jsonDoc1.object();
qDebug() << "obj1=" << obj1["sn"].toInt() << obj1["type"].toString() << endl;插入
jsonObject.insert("name", QString::number(i+1));
jsonObject.insert("age", i+18);
jsonObject.insert("time", QDateTime::currentDateTime().toString());json说明
/*【】是用来填充数据使用 */
(*configJson->RootObjPointer())["IP"]=jArray;
/*.value 这种方式是用来获取数据*/
(*configJson->RootObjPointer()).value("IP")=jArray;json注意事项:
数组中不能是00 "NightMode": [18, 00, 0, 6, 0, 0] //解析不出来
数组中是int类型的数据 不要用QString 去替换,会不成功。
修改json类型要修改他的指针,重新填充数据要重新赋值给上层的父类,保存才能达到效果,不能获取的只是临时变量。(如下例子)QJsonArray jArray= configJson->RootObj().value("IP").toArray();
jArray[4]= 12; //无效 (数组越界 )
jArray.insert(3,jArray); //ok (可以插入任意类型 )
jArray.replace(3,jArray); //ok (可以替换任意类型 )
jArray[0]= 54; //ok (数组不越界 )
(*configJson->RootObjPointer())["IP"]=jArray; //Ok (通过指针来获取“IP”,并赋值)
configJson->savejsonfile();案例1:
QString fileName = QCoreApplication::applicationDirPath();
fileName+="/pdoctor.json";
doctorjson = new Json(fileName);
QJsonArray doctor = doctorjson->Obj()["data"].toArray();
int row = doctor.count();
for (int i=0;i<row;i++)
{
}
doctor.at(i).toObject()["advice"].toObject()["adviceSeq"].toInt();
doctor.at(i).toObject()["advice"].toObject()["drugName"].toString();
doctor.at(i).toObject()["advice"].toObject()["adviceType"].toInt();
doctor.at(i).toObject()["advice"].toObject()["freq"].toString();
doctor.at(i).toObject()["advice"].toObject()["drugvolume"].toDouble();
doctor.at(i).toObject()["advice"].toObject()["drugDensity"].toDouble();案例2:
案例3:
/*****************************************************************************************/
QByteArray byte;
QFile file(file_path);
if(file.exists()){file.open(QIODevice::ReadOnly|QIODevice::Text);byte=file.readAll();file.close();
}
else
{cout<<"openFileError"<<endl;;
}
QJsonParseError json_error;
QJsonDocument jsonDoc(QJsondocument::fromJson(byte,&json_error));
if(json_error.err!=QJsonParseError::NoError)
{cout<<" json error "<<endl;
}
QJsonObject rootobj=jsonDoc.object();
//一般需要使用 rootobj.contains(xxx) 判断一下是否存在 这里我们就默认是存在的 。QJsonObject A_obj=rootobj.value("A").toObject();
A_obj["AA"]=33;QJsonArray B_array=rootobj.value("B").toArray();
QJsonObject B_Subobj=B_array[0].toObject();
QJsonArray b_array=B_Subobj.value("BB").toArray();
b_array.replace(0,"BBB");
B_Subobj["BB"]=b_array;
B_array.replace(0,B_Subobj);QJsonObject C_obj=rootobj.value("C").toObject();
QJsonArray c_array=C_obj.value("CC").toArray();
c_array.replace(0,"CCC");
C_obj["CC"]=c_array;rootobj["A"]=A_obj;
rootobj["B"]=B_array;
rootobj["C"]=C_obj;QFile file(file_path);
if(file.exists()){file.open(QIODevice::WriteOnly|QIODevice::Text);jsonDoc.setObject(rootobj);file.seek(0);file.write(jsonDoc.toJson());file.flush();file.close();
}dock案例:
#include "json.h"
Json::Json(QString fileName)
{jsonName=fileName;openjsonfile(jsonName);
}Json::~Json()
{savejsonfile();
}void Json::openjsonfile(QString name)
{if(QFile::exists(name)){QByteArray byte;QJsonDocument jsonDoc;QFile file;file.setFileName(name);file.open(QFile::ReadOnly|QIODevice::Text);byte= file.readAll();jsonDoc = QJsonDocument::fromJson(byte);//转换成文档对象if(jsonDoc.isObject()){ //判断文档对象中存储的数据是不是json对象isfile = true;rootobj = jsonDoc.object();//得到rootJson对象file.close();}}else{isfile = false;}
}
void Json::savejsonfile()
{QFile file;QJsonDocument jsonDoc(rootobj); //将Json对象,转换成Json文档
// jsonDoc.setObject(rootobj);file.setFileName(jsonName);file.open(QFile::WriteOnly|QIODevice::Text);file.seek(0);file.write(jsonDoc.toJson());file.flush();file.close();
}int Json::getKeyIntVal(QString key)
{return rootobj[key].toInt();
}QString Json::getKeyStringVal(QString key)
{return rootobj[key].toString();
}bool Json::getKeyBoolVal(QString key)
{return rootobj[key].toBool();
}//读取空值(因其没有对应的to类型函数,可使用下方类型接收或isNull()函数判断)
QVariant Json::getKeyVarialVal(QString key)
{return rootobj[key].toVariant();
}QJsonObject Json::getKeyQJsonObject(QString key)
{return rootobj[key].toObject();
}QJsonArray Json::getKeyQJsonArray(QString key)
{return rootobj[key].toArray();
}int Json::getArrayIndexIntVal(QString key, int index)
{return rootobj[key].toArray().at(index).toInt();
}QJsonObject Json::RootObj()
{return rootobj;
}QJsonObject* Json::RootObjPointer()
{return &rootobj;
}bool Json::getisfile()
{return isfile;
}void Json::insertKeyIntVal(QString key, int valu)
{rootobj[key]=valu;
}/*
*
*netjson->insertKeyBoolVal("NightMode",true); ok
*/
void Json::insertKeyBoolVal(QString key, bool valu)
{rootobj[key]=valu;
}/*
*netjson->insertKeyStringVal("NightMode","opopopo"); Ok
*/
void Json::insertKeyStringVal(QString key, QString valu)
{rootobj[key]=valu;
}/*
* QJsonArray c_JsArr;
* c_JsArr.append(12);
* c_JsArr.append(32);
* netjson->insertKeyArrayVal("NightMode",c_JsArr); //Ok
*/
void Json::insertKeyArrayVal(QString key, QJsonArray array)
{rootobj[key]= array;
}/*
* QJsonObject jsobject;jsobject["opo"] = "qqqqqq";jsobject["op1"] = 12;jsobject["op2"] = true;jsobject["op3"] = "rrrrrr";netjson->insertKeyObjectVal("NightMode",jsobject);
*
*/
void Json::insertKeyObjectVal(QString key, QJsonObject jsobject)
{rootobj[key]=jsobject;
}/*
* netjson->replaceKeyArrayIndexVal("NightMode",5,10); //ok
**/
void Json::replaceKeyArrayIndexVal(QString key, int index, int valu) //valu 为 QString 不能替换
{QJsonArray c_JsArr = rootobj.value(key).toArray();c_JsArr.replace(index,valu);rootobj[key]=c_JsArr;
}/* 数组里面添加QJsonArray
* QJsonArray c_JsArr;
* c_JsArr.append(12);
* c_JsArr.append(32);
* c_JsArr.replace(0,24); //替换
* netjson->insertArrayKeyAddArrayVal("NightMode",0,c_JsArr);
*/void Json::insertArrayKeyAddArrayVal(QString key, int index, QJsonArray valu)
{QJsonArray c_JsArr = rootobj.value(key).toArray();c_JsArr[index] = valu;rootobj[key]=c_JsArr;
}/*
* 数组里面添加QJsonObject
* QJsonObject jsobject;
* jsobject["opo"] = "qqqqqq";
* jsobject["op1"] = 12;
* jsobject["op2"] = true;
* jsobject["op3"] = "rrrrrr";
* netjson->insertArrayKeyAddObjectVal("NightMode",0,jsobject);
*/
void Json::insertArrayKeyAddObjectVal(QString key, int index, QJsonObject jsobject)
{QJsonArray c_JsArr = rootobj.value(key).toArray();c_JsArr[index] = jsobject;rootobj[key]=c_JsArr;
}#ifndef JSON_H
#define JSON_H#include <QtWidgets/QWidget>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QDebug>
#include <QString>
#include <QByteArray>
#include <QFile>class Json
{
public:Json(QString file);~Json();void openjsonfile(QString name);void savejsonfile();int getKeyIntVal(QString key);QString getKeyStringVal(QString key);bool getKeyBoolVal(QString key);QVariant getKeyVarialVal(QString key);QJsonArray getKeyQJsonArray(QString key);QJsonObject getKeyQJsonObject(QString key);int getArrayIndexIntVal(QString key, int index);QJsonObject RootObj();QJsonObject* RootObjPointer();bool getisfile();//将键值对添加到Json对象中void insertKeyIntVal(QString key,int valu);void insertKeyBoolVal(QString key,bool valu);void insertKeyStringVal(QString key,QString valu);void insertKeyArrayVal(QString key,QJsonArray array);void insertKeyObjectVal(QString key, QJsonObject jsobject);void replaceKeyArrayIndexVal(QString key, int index, int valu);void insertArrayKeyAddArrayVal(QString key, int index, QJsonArray valu);void insertArrayKeyAddObjectVal(QString key, int index, QJsonObject jsobject);
private:QString jsonName;QJsonObject rootobj;bool isfile ;
};#endif // JSON_H
相关文章:
【Qt-数据库】
Qt编程指南 ■ SQLite■ CSV■ JSON ■ SQLite Qt 提供了很多操作数据库的类, SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于 250KiB。 SQLite 是一个进程内的库,实现了自给自足的、无…...
windows文件名命名规范(文件名规范、命名规则、避免特殊字符、注意文件名长度限制260个字符)
文章目录 Windows文件名命名规范1. 基本规则1.1 避免使用特殊字符1.2 限制文件名长度1.3 避免使用预留名称 2. 最佳实践2.1 使用描述性名称2.2 使用连字符或下划线代替空格2.3 使用日期和版本号 3. 实用技巧3.1 批量重命名文件3.2 使用PowerShell进行高级文件操作 Windows文件名…...
如何修改MySQL的默认端口
MySQL是世界上最流行的开源关系型数据库管理系统之一。在某些情况下,由于安全性、网络策略或端口冲突的原因,数据库管理员可能需要更改MySQL服务的默认监听端口。本文将指导您如何在不同的操作系统上更改MySQL的默认端口。 理解MySQL配置文件 MySQL的配…...

Android笔记(二十一):Room组件实现Android应用的持久化处理
一、Room组件概述 Room是Android JetPack架构组件之一,是一个持久处理的库。Room提供了在SQLite数据库上提供抽象层,使之实现数据访问。 (1)实体类(Entity):映射并封装了数据库对应的数据表中…...
uniapp中各种状态的按钮
当涉及状态按钮时,UniApp提供了丰富的选择。UniApp中的状态按钮可以是开关按钮、单选按钮、多选按钮等。开发者可以根据具体需求选择使用合适的状态按钮组件。对于状态按钮,UniApp提供了丰富的API和事件,可以轻松实现状态切换、状态监听等功能…...

模式识别与机器学习-判别式分类器
模式识别与机器学习-判别式分类器 生成式模型和判别式模型的区别线性判别函数多分类情况多分类情况1多分类情况2多分类情况3 例题 广义线性判别函数实例 分段线性判别函数Fisher线性判别感知机算法例:感知机多类别分类 谨以此博客作为学习期间的记录 生成式模型和判…...
c++11 标准模板(STL)(std::pair)(七)访问 pair 的一个元素
定义于头文件 <utility> std::pair 是一个结构体模板,其可于一个单元存储两个相异对象。 pair 是 std::tuple 的拥有两个元素的特殊情况。 访问 pair 的一个元素 std::get(std::pair) template< size_t I, class T1, class T2 > typename std::tuple…...

IP 地址归属地查询
IP 地址归属地查询 1. IP 地址归属地查询2. IP 地址归属地查询References 1. IP 地址归属地查询 https://tool.lu/ip/index.html 2. IP 地址归属地查询 https://www.ip.cn/ip/.html References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/...

实战经验分享:在Java中灵活应用Excel注释和批注
本文由葡萄城技术团队原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 前言 注释及批注是 Excel 中比较常用的功能,注释往往针对单元格,起到解释说明的作用&a…...
AUTOSAR从入门到精通-车载以太网(三)
目录 前言 原理 车载以太网总体架构 物理层 数据链路层 以太网帧格式<...

【自然语言处理】用Python从文本中删除个人信息-第二部分
自我介绍 做一个简单介绍,酒架年近48 ,有20多年IT工作经历,目前在一家500强做企业架构.因为工作需要,另外也因为兴趣涉猎比较广,为了自己学习建立了三个博客,分别是【全球IT瞭望】,【…...
设计模式之-中介者模式,快速掌握中介者模式,通俗易懂的讲解中介者模式以及它的使用场景
系列文章目录 设计模式之-6大设计原则简单易懂的理解以及它们的适用场景和代码示列 设计模式之-单列设计模式,5种单例设计模式使用场景以及它们的优缺点 设计模式之-3种常见的工厂模式简单工厂模式、工厂方法模式和抽象工厂模式,每一种模式的概念、使用…...

12.25
led.c #include "led.h" void all_led_init() {RCC_GPIO | (0X3<<4);//时钟使能GPIOE_MODER &(~(0X3<<20));//设置PE10输出GPIOE_MODER | (0X1<<20);//设置PE10为推挽输出GPIOE_OTYPER &(~(0x1<<10));//PE10为低速输出GPIOE_OSPEED…...
MySQL5.7的几种安装方式总结(排错踩坑呕心沥血的经历)
包安装 添加国内源:mysql | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 注意:5.7安装之后有一个临时密码,进行登录并修改新密码后才可以对mysql进行操作。 可以yun list看看各个系统光盘自带的都是什么版本&…...

zookeeper基本使用
目录 环境搭建 单机版搭建 集群版搭建 基本语法使用 可视化客户端 数据结构 节点分类 1. 持久节点 2. 临时节点 3. 有序节点 4. 容器节点 5. TTL节点 节点状态 监听机制 watch监听 永久性watch 应用场景 1. 实现分布式锁 2. 乐观锁更新数据 应用场景总结 选…...

【华为机试】2023年真题B卷(python)-分月饼
一、题目 题目描述: 中秋节公司分月饼,m个员工,买了n个月饼,m<n,每个员工至少分1个月饼,但可以分多个,单人份到最多月饼的个数为Max1,单人分到第二多月饼的个数是Max2,…...
EtherCAT主站SOEM -- 11 -- EtherCAT从站 XML 文件解析
EtherCAT主站SOEM -- 11 -- EtherCAT从站 XML 文件解析 1 EtherCAT 从站信息规范1.1 XML 文件说明1.1.1 XML 数据类型1.1.2 EtherCATInfo1.1.3 Groups1.1.4 Devices1.1.5 Modules1.1.6 Types1.1.6.1 AccessType 的组成1.1.6.2 ArraylnfoType 的组成1.1.6.3 DeviceType 的组成1.…...

YOLOv5算法改进(23)— 更换主干网络GhostNet + 添加CA注意力机制 + 引入GhostConv
前言:Hello大家好,我是小哥谈。本节课就让我们结合论文来对YOLOv5进行组合改进(更换主干网络GhostNet + 添加CA注意力机制 + 引入GhostConv),希望同学们学完本节课可以有所启迪,并且后期可以自行进行YOLOv5算法的改进!🌈 前期回顾: YOLOv5算法改进(1)— 如何去…...
centos系统部署rancher1.6版本并部署服务
1. centos上部署docker. 请参考 博客 2. 用docker安装rancher1.6 sudo docker run -d -v /mnt/rancher/db:/var/lib/mysql --restartunless-stopped -p 8080:8080 rancher/server3.浏览器登录做设置 3.1 浏览器打开 1.117.92.32:8080 #直接就登录了 3.2 第一次进入&am…...
Matlab实时读取串口数据并实时画图方法
** Matlab实时读取串口数据并实时画图方法 ** 按照数据串口协议如:$KT2,1.80,88.18,39.54,42.86,LO[0.72,-1.04,0.35],举例。 s serialport("COM12",115200,"Timeout",5); poszeros(100000,3); j1; data1 read(s,1,"uint8&…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...