当前位置: 首页 > news >正文

Qt使用sqlite数据库及项目实战

一.sqlite使用介绍

在Qt中使用SQLite数据库非常简单,SQLite是一个轻量级的嵌入式数据库,不需要单独的数据库服务器,完全使用本地文件来存储数据。

当在Qt中使用SQLite数据库时,需要涉及到一些SQL语句以及Qt中的相关函数,接下来我将从头开始介绍所有涉及的语句以及相应的解释。

1. 连接到数据库:addDatabase

在Qt中,你可以使用QSqlDatabase来连接数据库。首先需要添加数据库类型,然后指定数据库的名称:

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("mydatabase.db");
if(!db.open()) {qDebug() << "无法连接到数据库";return;
}

在这段代码中,我们首先创建了一个名为mydatabase.db的SQLite数据库,然后通过open()函数来打开数据库连接。如果连接失败,将会输出错误信息。

2. 创建表:CREATE TABLE

一般来说,你需要在数据库中创建表来存储数据。这可以通过执行CREATE TABLE语句来实现:

QSqlQuery query;
query.exec("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)");

这里我们使用exec()函数执行SQL语句,创建了一个名为users的表,包含id、name和age三个列。

3. 插入数据:INSERT

当需要在表中插入新的数据时,可以使用SQL的INSERT INTO语句。在Qt中,可以使用QSqlQuery对象的prepare()和bindValue()函数来执行预处理插入语句:

  • 常规的数据库插入语句
INSERT into users(id,name,age)VALUES(111,"name",12)
  • Qt中
QString name = "Alice";
int age = 25;
QSqlQuery query;
query.prepare("INSERT INTO users (name, age) VALUES (:name, :age)");
query.bindValue(":name", name);
query.bindValue(":age", age);
if(!query.exec()) {qDebug() << "插入数据失败:" << query.lastError().text();
}
  • prepare和bindValue函数介绍

当在Qt中进行数据库操作时,使用query.prepare()和query.bindValue()方法可以帮助你执行预处理SQL语句并绑定参数的值。这两个方法在插入操作中起到了重要作用,下面我将详细介绍它们的功能和作用:

  1. query.prepare():

在Qt中,query.prepare()方法用于准备要执行的SQL语句。它的主要作用是将SQL语句中的参数部分用占位符(如:variable)代替,从而形成一个预处理的SQL语句。通过这种方式,可以避免SQL注入攻击,并提高程序的安全性。

例如,在插入操作中,你可能会使用INSERT INTO table_name (column1, column2, …) VALUES (:value1, :value2, …)这样的SQL语句,其中的:value1、:value2是占位符,用于将实际的数值动态地填充进去。使用query.prepare()方法可以将这个SQL语句准备好,等待绑定参数值。

  1. query.bindValue():

一旦调用了query.prepare()方法准备好了SQL语句,接下来就可以使用query.bindValue()方法为每个占位符绑定具体的数值。这个方法的作用是设置预处理语句中的占位符的值,从而将真实的数据插入到SQL语句中。

例如,在前面的插入操作示例中,我们对name和age这两个占位符使用了query.bindValue()方法,将实际的name和age变量的值绑定到了这两个占位符上。

使用query.bindValue()方法可以方便地将变量的值插入到SQL语句中,同时还可以防止数据类型转换错误和SQL注入攻击。

综上所述,query.prepare()方法用于准备预处理SQL语句,并替换其中的占位符,而query.bindValue()方法则用于将实际的数值绑定到这些占位符上,从而完成对数据库的插入操作。这两个方法的结合使用可以简化代码编写,同时提高程序的安全性和可维护性。

4. 查询数据:SELECT

查询数据最常见的方式是使用SELECT语句。在Qt中,我们可以通过exec()函数执行SELECT语句,并使用next()函数来逐行获取结果:

QSqlQuery query;
query.exec("SELECT * FROM users");
while(query.next()) {int id = query.value(0).toInt();QString name = query.value(1).toString();int age = query.value(2).toInt();qDebug() << "ID:" << id << " Name:" << name << " Age:" << age;
}

这段代码遍历了users表中的所有行,并输出每一行的ID、名称和年龄。

  • query.next介绍

在Qt中,query.next()方法用于遍历查询结果集中的下一行数据。当执行SELECT查询语句并通过exec()方法获取结果集后,可以使用query.next()方法逐行访问查询结果中的数据。

每次调用query.next()方法,会将查询结果集中的指针移到下一行数据。如果存在下一行数据,则该方法返回true,并允许获取下一行数据;如果不存在下一行数据,则返回false,表示已经遍历完所有结果。

一般来说,可以在一个循环中使用query.next()方法来遍历整个查询结果集,逐行获取数据并进行相应的处理。在循环中,通常会结合query.value()方法用于获取特定列的值。

5. 更新数据:UPDATE

在 Qt 中使用 SQLite 实现更新(修改)数据库操作可以通过执行 SQL UPDATE 语句来实现。下面是一个简单的示例代码,演示了如何使用 Qt 和 SQLite 执行更新操作:

#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);// 连接到SQLite数据库QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("database.db"); // 指定SQLite数据库文件if (!db.open()) {qDebug() << "Error: Unable to connect to database.";return 1;}// 执行 UPDATE 操作QSqlQuery query;query.prepare("UPDATE student SET name = :newName WHERE id = :id");query.bindValue(":newName", "New Name"); // 设置要更新的新名称query.bindValue(":id", 1); // 设置要更新的记录的 IDif (query.exec()) {qDebug() << "Update successful";} else {qDebug() << "Update failed:" << query.lastError().text();}return app.exec();
}

6. 删除数据:DELETE

使用 QSqlQuery 类删除数据:

QSqlQuery query;
query.prepare("DELETE FROM your_table WHERE condition = :condition");  // 设置删除语句
query.bindValue(":condition", value);  // 绑定条件值
bool success = query.exec();  // 执行删除操作
if(success) {// 删除成功
} else {// 删除失败,处理错误qDebug() << "Error:" << query.lastError().text();
}

7. 更新数据库中的数据:submitAll

  • 这是对模型进行了修改,将数据提交回数据库中,以保持同步。
// 创建 QSqlTableModel 并设置数据库表QSqlTableModel model;model.setTable("student");model.select(); // 从数据库中选择数据// 创建 QTableView 并设置模型QTableView tableView;tableView.setModel(&model);// 创建一个按钮,当点击时提交更新QPushButton updateButton("Update Database");QObject::connect(&updateButton, &QPushButton::clicked, [&model](){if (model.submitAll()) {qDebug() << "Database update successful";} else {qDebug() << "Database update failed:" << model.lastError().text();}});
  • model.submitAll介绍

QSqlTableModel 中的 submitAll() 函数是用于将对模型数据的更改提交到数据库中的方法。当您在 QTableView 中对数据进行了修改、插入或删除等操作后,调用 submitAll() 函数可将这些更改应用到数据库中。

submitAll() 函数会执行以下操作:

  1. 检查模型中的每一行,如果该行的状态为 Inserted、Deleted 或 Modified,则将对应的更改提交到数据库中。
  2. 如果提交成功,会返回 true;如果提交失败,会返回 false。您可以通过检查返回值来确定提交是否成功。
  3. 如果提交失败,您可以调用 model.lastError().text() 来获取详细的错误信息。这将返回一个描述在提交过程中发生的错误的字符串。

在模型视图的结构中,对model是临时修改数据的中转站。

8. 更新QSqlQueryModel中的数据

QSqlQueryModel 是一个只读模型,无法直接编辑数据,因此更新数据的方式不同于可编辑的模型,比如 QSqlTableModel。如果您想要更新 QSqlQueryModel 中的数据,可以重新执行查询语句或者重新设置查询。

以下是更新 QSqlQueryModel 中数据的一种常见方法:

  1. 重新执行查询语句:您可以重新设置 QSqlQueryModel 的查询语句,然后调用 setQuery() 方法重新执行查询。这将重新从数据库中读取数据并更新模型中的数据。
QSqlQueryModel model;
model.setQuery("SELECT * FROM your_table");
  1. 使用 clear() 方法清空数据:如果需要清空 QSqlQueryModel 中的数据,您可以调用 clear() 方法。清空数据后,您可以重新设置查询或数据源,从而实现更新。
model.clear();

需要注意的是,QSqlQueryModel 是一个只读模型,不支持直接编辑数据,如果您需要在界面上进行编辑和更新操作,可以考虑使用 QSqlTableModel 或自定义的 QAbstractTableModel。

9. 对指定列进行排序

  • 这是对模型进行排序
// 创建 QSqlQueryModel 并设置查询语句
QSqlQueryModel *queryModel = new QSqlQueryModel;
queryModel->setQuery("SELECT * FROM your_table");// 创建 QSortFilterProxyModel 并设置源模型为 QSqlQueryModel
QSortFilterProxyModel *sortModel = new QSortFilterProxyModel(this);
sortModel->setSourceModel(queryModel);// 设置排序的列索引
int sortColumn = 1; // 假设要按第1列排序
sortModel->sort(sortColumn, Qt::AscendingOrder); // 进行升序排序// 将排序后的模型设置给视图
yourTableView->setModel(sortModel);
  • 对数据库进行排序
-- 以id列的升序方式进行排序
SELECT id, name, age
FROM your_table
ORDER BY id ASC;SELECT id ,name ,score  FROM student ORDER BY id DESC//对模型中的数据进行排序
model->setQuery("SELECT id, name, score FROM student ORDER BY id DESC");

二.成绩管理系统实战

1. 项目效果

在这里插入图片描述

  • 项目说明:底层存储数据用的是sqlite,界面展示数据用的是tableView和QSqlQueryModel的视图模型模式。

2. 项目源码:

  • 类定义
#ifndef STUDENTDLG_H
#define STUDENTDLG_H#include <QDialog>#include <QSqlDatabase> // 专用于连接、创建数据库
#include <QSqlQuery> // 专用于DML(数据操纵语言)、DDL(数据定义语言)
#include <QSqlQueryModel>//数据库模型,用来和tableview关联
#include <QSqlError>
#include <QDebug>
#include <QMessageBox>QT_BEGIN_NAMESPACE
namespace Ui { class StudentDlg; }
QT_END_NAMESPACEclass StudentDlg : public QDialog
{Q_OBJECTpublic:StudentDlg(QWidget *parent = nullptr);~StudentDlg();private slots:void on_pushButtonSort_clicked();void on_pushButton_INSERT_clicked();void on_pushButton_DELETE_clicked();void on_pushButton_UPDATE_clicked();void on_pushButton_SEARCH_clicked();
private: void CreateDatabaseFunc();  // 创建SQLite数据库void CreateTableFunc();     // 创建SQLite数据表void QueryTableFunc();      // 执行查询操作QSqlDatabase sqldb;         // 创建Qt和数据库链接QSqlQueryModel *model=nullptr;//用来存储数据
private:Ui::StudentDlg *ui;};
#endif // STUDENTDLG_H
  • 类实现
#include "studentdlg.h"
#include "ui_studentdlg.h"
#include<QSortFilterProxyModel>StudentDlg::StudentDlg(QWidget *parent): QDialog(parent), ui(new Ui::StudentDlg)
{ui->setupUi(this);// 调用函数创建且打开数据库CreateDatabaseFunc();// 调用函数创建数据表CreateTableFunc();
}StudentDlg::~StudentDlg()
{delete ui;
}void StudentDlg::CreateDatabaseFunc()  // 创建SQLite数据库
{// 1:添加数据库驱动sqldb=QSqlDatabase::addDatabase("QSQLITE");// 2:设置数据库名称sqldb.setDatabaseName("studentmis.db");// 3:打开此数据库是否成功if(sqldb.open()==true){QMessageBox::information(0,"正确","恭喜你,数据库打开成功!",QMessageBox::Ok);}else{QMessageBox::critical(0,"错误","数据库打开失败,请重新检测!",QMessageBox::Ok);}
}void StudentDlg::CreateTableFunc()     // 创建SQLite数据表
{QSqlQuery createquery;// 创建SQL语句QString strsql=QString("CREATE TABLE IF NOT EXISTS student(""id int primary key not null,""name text not null,""score real not null)");// 执行SQL语句if(createquery.exec(strsql)==false){QMessageBox::critical(0,"失败","数据表创建失败,请重新检查!",QMessageBox::Ok);}else{QMessageBox::information(0,"成功","恭喜你,数据表创建成功!",QMessageBox::Ok);}// 准备数据模型model = new QSqlQueryModel();model->setQuery("SELECT id, name, score FROM student"); // 执行查询// 将数据模型与QTableView绑定//QTableView *tableView = new QTableView();ui-> tableView->setModel(model);ui->tableView->resizeColumnsToContents(); // 调整列宽度使数据能够完全显示// 显示QTableViewui->tableView->show();}
void StudentDlg::QueryTableFunc()      // 执行查询操作
{QSqlQuery query;query.exec("SELECT * FROM users");while(query.next()) {int id = query.value(0).toInt();QString name = query.value(1).toString();double score = query.value(2).toDouble();qDebug() << "ID:" << id << " Name:" << name << " Score:" << score;}}void StudentDlg::on_pushButtonSort_clicked()
{//    QSortFilterProxyModel *sortModel = new QSortFilterProxyModel(this);
//    sortModel->setSourceModel(model);//    // 设置排序的列索引
//    int sortColumn = 1; // 假设要按第1列排序
//    sortModel->sort(sortColumn, Qt::DescendingOrder); // 进行升序排序//    // 将排序后的模型设置给视图
//    ui->tableView->setModel(sortModel);//    //使用sql语句进行操作
//    QSqlQuery query;
//    query.exec("SELECT id ,name ,score  FROM student ORDER BY id DESC");//更新数据库中的数据model->setQuery("SELECT id, name, score FROM student ORDER BY id DESC");//model->setQuery("SELECT * FROM student");ui->tableView->viewport()->update();
}void StudentDlg::on_pushButton_INSERT_clicked()
{QSqlQuery sqlquery;int id=ui->lineEdit_ID->text().toInt();if(id==0){QMessageBox::critical(this,"失败","提示:输入错误?学号不能为0?",QMessageBox::Ok);return ;}QString name=ui->lineEdit_NAME->text();if(name==""){QMessageBox::critical(this,"失败","提示:输入错误?姓名不能为空?",QMessageBox::Ok);return ;}double score=ui->lineEdit_SCORE->text().toDouble();if(score<0 || score>100){QMessageBox::critical(this,"失败","提示:输入错误?分数范围(0-100)?",QMessageBox::Ok);return ;}QString strs=QString("insert into student ""values(%1,'%2',%3)").arg(id).arg(name).arg(score);if(sqlquery.exec(strs)==false){QMessageBox::critical(0,"失败","向数据表插入记录失败,请重新检查!",QMessageBox::Ok);}else{QMessageBox::information(0,"成功","恭喜你,向数据表插入记录成功!",QMessageBox::Ok);}}void StudentDlg::on_pushButton_DELETE_clicked()
{int id = ui->lineEdit_ID->text().toInt();QSqlQuery query;query.prepare("DELETE FROM student WHERE id = :id");  // 设置删除语句query.bindValue(":id", id);  // 绑定条件值bool success = query.exec();  // 执行删除操作if(success) {// 删除成功} else {// 删除失败,处理错误qDebug() << "Error:" << query.lastError().text();}//更新数据库中的数据model->setQuery("SELECT * FROM student");ui->tableView->viewport()->update();
}void StudentDlg::on_pushButton_UPDATE_clicked()
{// 执行 UPDATE 操作QString New_Name=ui->lineEdit_NAME->text();int id=ui->lineEdit_ID->text().toUInt();QSqlQuery query;query.prepare("UPDATE student SET name = :newName WHERE id = :id");query.bindValue(":newName", New_Name); // 设置要更新的新名称query.bindValue(":id", id); // 设置要更新的记录的 IDif (query.exec()) {qDebug() << "Update successful";} else {qDebug() << "Update failed:" << query.lastError().text();}}void StudentDlg::on_pushButton_SEARCH_clicked()
{QSqlQuery query;query.exec("SELECT * FROM student");while(query.next()) {int id = query.value(0).toInt();QString name = query.value(1).toString();double score = query.value(2).toDouble();qDebug() << "ID:" << id << " Name:" << name << " Score:" << score;}//更新数据库中的数据model->setQuery("SELECT * FROM student");ui->tableView->viewport()->update();
}

相关文章:

Qt使用sqlite数据库及项目实战

一.sqlite使用介绍 在Qt中使用SQLite数据库非常简单&#xff0c;SQLite是一个轻量级的嵌入式数据库&#xff0c;不需要单独的数据库服务器&#xff0c;完全使用本地文件来存储数据。 当在Qt中使用SQLite数据库时&#xff0c;需要涉及到一些SQL语句以及Qt中的相关函数&#xf…...

开源模型应用落地-FastAPI-助力模型交互-进阶篇(一)

一、前言 FastAPI 的高级用法可以为开发人员带来许多好处。它能帮助实现更复杂的路由逻辑和参数处理&#xff0c;使应用程序能够处理各种不同的请求场景&#xff0c;提高应用程序的灵活性和可扩展性。 在数据验证和转换方面&#xff0c;高级用法提供了更精细和准确的控制&#…...

精准选择广告工具,提升推广效果

在考虑使用巨量引擎之前&#xff0c;我们首先要明白它的本质。巨量引擎是一个付费广告平台&#xff0c;包含了多种推广工具&#xff0c;如巨量ID、巨量千川、巨量本地推&#xff0c;以及企业蓝V等。很多人希望通过这个平台提升抖音账号的流量和曝光度&#xff0c;但真正有效的流…...

Swagger的原理及应用详解(六)

本系列文章简介: 在当今快速发展的软件开发领域,特别是随着微服务架构和前后端分离开发模式的普及,API(Application Programming Interface,应用程序编程接口)的设计与管理变得愈发重要。一个清晰、准确且易于理解的API文档不仅能够提升开发效率,还能促进前后端开发者之…...

世界人工智能大会今日开幕:人工智能如何成为引领发展的新引擎

人工智能如何成为引领上海发展的新引擎&#xff1f;今日&#xff08;7月4日&#xff09;开幕的2024世界人工智能大会暨人工智能全球治理高级别会议&#xff08;简称“WAIC 2024”&#xff09;将带来答案。 “新”和“全”是今年大会的亮点所在&#xff1a;“新”在于技术新&…...

tinyshop项目部署

参考软件测试之测试用例设计&#xff08;四&#xff09;_管理后台 测试用例-CSDN博客 1、下载xampp 2、修改apache和mysql的端口分别为4431 &#xff0c;8013和3306 3、访问页面&#xff1a;输入ip:端口号&#xff0c;出现以下页面即成功 4、安装tinyshop商城 将解压的tinys…...

Gemini for China 大更新,现已上架 Android APP!

官网&#xff1a;https://gemini.fostmar.online/ Android APP&#xff1a;https://gemini.fostmar.online/gemini_1.0.apk 一、Android APP 如果是 Android 设备&#xff0c;则会直接识别到并给下载链接。PC 直接对话即可。 二、聊天记录 现在 Gemini for China&#xff…...

Unity渲染管线介绍

Unity中的渲染管线渲染场景主要分为三个阶段 剔除&#xff08;Culling&#xff09; 剔除摄像机不可见对象&#xff08;视锥体剔除Frustum Culling&#xff09;和被遮挡对象&#xff08;遮挡剔除Occlusion Culling&#xff09;。 渲染&#xff08;Rendering&#xff09; 将可见…...

【UML用户指南】-31-对体系结构建模-制品图

目录 1、对源代码建模 2、对可执行程序的发布建模 3、对物理数据库建模 4、对可适应系统建模 制品图是对面向对象系统的物理方面进行建模时要用到的两种图之一。制品图展示一组制品之间的组织以及其间依赖关系。 利用制品图可以对系统的静态实现视图建模。这包括对存在于结…...

《基于 Kafka + Flink + ES 实现危急值处理措施推荐和范围校准》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; 近期刚转战 CSDN&#xff0c;会严格把控文章质量&#xff0c;绝不滥竽充数&#xff0c;欢迎多多交流。&am…...

计算机的进制转换

十进制&#xff1a;以0-9这九个数字组成。 二进制&#xff1a;由0和1两个数字组成。 八进制&#xff1a;由0-7数字组成&#xff0c;不存在8和9。 十六进制&#xff1a;由0-9和A-F组成。A-F对应的是10-15。 ____________ 十进制 1 2 3 4 5 6 7 8 9 10 二进制 0 1 10 11 1…...

String类(STL开始)

相信大家都知道STL在C中的重要性&#xff0c;作为其模板库中的一部分&#xff0c;包含了常见的数据结构和算法&#xff0c;是C的标准库 而我们今天要讲的String类&#xff08;String底层是一个字符顺序数组的顺序表对象&#xff0c;可以归类为容器&#xff09;&#xff0c;其实…...

【数据结构】单链表:数据结构中的舞者,穿梭于理论与实践的舞池

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 数据结构与算法 先赞后看&#xff0c;已成习惯 创作不易&#xff0c;多多支持&#xff01; 一、链表的概念和结构 1.1 链表的概念 在上一篇文章中&#xff0c;我们了解了线性表(linear list)&#xff0c;并且学习了其…...

html三级菜单

示例 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>Menu Example</title> <link re…...

【人工智能】—基于成都市各区(市)县租房价格预测建模研究

引言 随着城市化进程的加速&#xff0c;人口流动日益频繁&#xff0c;租房市场作为城市生活的重要组成部分&#xff0c;其价格波动对居民生活质量和城市经济发展具有显著影响。成都市&#xff0c;作为中国西部地区的经济、文化、交通和科技中心&#xff0c;近年来吸引了大量人…...

3213. 最小代价构造字符串

Powered by:NEFU AB-IN Link 文章目录 3213. 最小代价构造字符串题意思路代码 3213. 最小代价构造字符串 题意 给你一个字符串 target、一个字符串数组 words 以及一个整数数组 costs&#xff0c;这两个数组长度相同。 设想一个空字符串 s。 你可以执行以下操作任意次数&a…...

提取重复数据

直接上控制台代码&#xff1a; Module Module1Sub Main()Console.WriteLine("请输入数据&#xff0c;以""&#xff0c;""相隔&#xff1a;")Dim str As String Console.ReadLineDim result From x In str.Split(",")Group By x Int…...

Go语言标准库之log和三方库zap

一、Log 1.1 logger基本使用 Go语言内置的log包实现了简单的日志服务。本包也提供了一个预定义的“标准”logger&#xff0c;可以通过调用函数Print系列(Print|Printf|Println)、Fatal系列&#xff08;Fatal|Fatalf|Fatalln)、和Panic系列&#xff08;Panic|Panicf|Panicln)来…...

Linux:进程终止和进程替换

Linux&#xff1a;Linux&#xff1a;进程终止和进程替换 一、进程终止1.1 进程退出场景和创建退出方式 1.2 exit 和 _exit区别二、进程程序替换2.1 进程替换函数2.2 函数解释及命名解释函数解释命名解释 2.3 单进程程序替换&#xff08;无子进程&#xff09;2.3.1 带l函数进程替…...

使用Java实现异步消息处理与队列消费

使用Java实现异步消息处理与队列消费 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在现代软件系统中&#xff0c;处理异步消息和队列消费是常见的需求。通过…...

使用C++实现ATM系统,谈谈思路及代码实现

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…...

相机光学(二十四)——CRA角度

CRA角度 0.参考资料1.什么是CRA角度2.为什么 CRA 会导致luma shading3.为什么 CRA 会导致color shading4.CRA相差过大的具体表现5.CRA Matching6.怎样选择sensor的CRA 0.参考资料 1.芯片CRA角度与镜头的匹配关系&#xff08;一&#xff09;   2.芯片CRA角度与镜头选型的匹配关…...

python函数和c的区别有哪些

Python有很多内置函数&#xff08;build in function&#xff09;&#xff0c;不需要写头文件&#xff0c;Python还有很多强大的模块&#xff0c;需要时导入便可。C语言在这一点上远不及Python&#xff0c;大多时候都需要自己手动实现。 C语言中的函数&#xff0c;有着严格的顺…...

速看!这主食冻干评测极可能被商家恶意举报~PR、希喂和SC真实测评

我是一名专注于宠物健康的营养师&#xff0c;日常大部分时间都在与猫咪和狗狗为伴&#xff0c;对它们入店时的身体状况往往能迅速做出初步判断。当前&#xff0c;多数家养猫咪面临的肥胖和肝损伤问题尤为突出&#xff0c;尽管医疗干预能缓解病情&#xff0c;但要从根本上解决还…...

股票数据分析(K线图、均值图、MACD图、RSI图)--股票日数据

数据 数据是上证指数日行情数据&#xff0c;股票代码000002.sz&#xff0c;原始数据shdata示例如下&#xff1a; 读取数据&#xff1a; import numpy as np import pandas as pd import mplfinance as mpf import matplotlib.pyplot as plt from datetime import datetime imp…...

重写equals()方法为什么同时要重写hashcode()

equals()方法 equals()方法是Object类中的一个方法&#xff0c;在Object类中&#xff0c;equals等同于。 在不同的类中&#xff0c;往往会对equals()按需求进行重写。重写的目的都是&#xff1a;用于比较两个对象是否 "相等"。如果两个对象的内容相同&#xff0c;那…...

安全及应用(更新)

一、账号安全 1.1系统帐号清理 #查看/sbin/nologin结尾的文件并统计 [rootrootlocalhost ~]# grep /sbin/nologin$ /etc/passwd |wc -l 40#查看apache登录的shell [rootrootlocalhost ~]# grep apache /etc/passwd apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin#改变…...

Hadoop权威指南-读书笔记-03-Hadoop分布式文件系统

Hadoop权威指南-读书笔记 记录一下读这本书的时候觉得有意思或者重要的点~ 还是老样子~挑重点记录哈&#x1f601;有兴趣的小伙伴可以去看看原著&#x1f60a; 第三章 Hadoop分布式文件系统 当数据集的大小超过一台独立的物理计算机的存储能力时&#xff0c;就有必要对它进行分…...

Rust入门实战 编写Minecraft启动器#2建立资源模型

首发于Enaium的个人博客 我们需要声明几个结构体来存储游戏的资源信息&#xff0c;之后我们需要将json文件解析成这几个结构体&#xff0c;所以我们需要添加serde依赖。 serde { version "1.0", features ["derive"] }资源相关asset.rs use serde::De…...

小白学C++(第一天)基础入门

温馨提醒&#xff1a;本篇文章&#xff0c;请各位c基础不行的童鞋不要贸然观看 C的第一个程序 第一个关键字namespace namespace 是定义空间的名字的关键字&#xff0c;使用格式格式如下&#xff1a; namespace 空间名 { } 其中{ }内的命名空间的成员&#xff0c;可以定义…...