Qt连接Sqlite3并使用Qtableview实时显示数据,重写QSqlQueryModel实现文本居中

news2025/4/23 9:22:23

文章目录

  • 前言
  • 一、引入SQL模块
  • 二、数据库的基本操作
  • 三、示例完整代码
  • 四、下载链接
  • 总结


前言

什么是 SQLite?
SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。(来自菜鸟教程SQLite简介)

在我以前的文章有介绍Qt下MySQL数据库的使用,需要进行MySQL服务器的连接,有时候还需要编译Qt源码来获取MySQL驱动,使用起来有点麻烦。如果我们的项目不需要一个单独的服务器进程或操作的系统(无服务器的),这时候可以选择使用SQLite数据库来保存数据,这里介绍一下Qt中自带驱动的Sqlite3数据库的使用,并结合相应的示例进行讲解,标题功能的体现见示例完整代码,如有错误之处,欢迎大家批评指正。

项目效果
请添加图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、引入SQL模块

在Qt项目文件(.pro文件)中,加入SQL模块:

QT += sql

有的pro中是有“Qt += core gui”的,可以直接加在这后面:

QT += core gui sql

添加头文件

#include <QSqlQuery>
#include <QSqlError>
#include <QSqlDatabase>
#include <QSqlQueryModel>

二、数据库的基本操作

1.在指定保存路径下以当天日期为名称创建数据库并打开

QString dbPath = QCoreApplication::applicationDirPath() + "/SaveDbFile/";
QString dbName = dbPath + QDate::currentDate().toString("yyyyMMdd") + ".db";
m_db = QSqlDatabase::addDatabase("QSQLITE");
m_db.setDatabaseName(dbName);
if(!m_db.open())
{
    //打开失败打印
    qDebug()<<"数据库打开失败..."<<m_db.lastError();
}

2.创建名为dataTable的数据表

QSqlQuery query(m_db);
QString createStr = "create table if not exists dataTable(id integer primary key autoincrement, data varchar(30), time datetime)";
query.exec(createStr);

3.向dataTable表中插入数据

QSqlQuery query(m_db);
query.prepare("insert into dataTable(data,time) values(:data,:time)");   //插入数据
query.bindValue(":data",data);
query.bindValue(":time",time);
query.exec();

三、示例完整代码

1.MySqlite3.pro

QT       += core gui sql

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
    main.cpp \
    mainwindow.cpp \
    mysqlmodel.cpp

HEADERS += \
    mainwindow.h \
    mysqlmodel.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

2.mysqlmodel.h

#ifndef MYSQLMODEL_H
#define MYSQLMODEL_H

#include <QSqlQueryModel>

class MySqlModel : public QSqlQueryModel
{
    Q_OBJECT

public:
    MySqlModel(QObject *parent = nullptr);
    QVariant data(const QModelIndex &item, int role) const override;

};
#endif // MYSQLMODEL_H

3.mysqlmodel.cpp

#include "mysqlmodel.h"

MySqlModel::MySqlModel(QObject *parent)
    : QSqlQueryModel(parent)
{

}

//设置文本居中
QVariant MySqlModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const
{
    QVariant value = QSqlQueryModel::data(index,role);
    if(role == Qt::TextAlignmentRole)
    {
        value = Qt::AlignCenter;   //文本居中
        return value;
    }
    return value;
}

4.mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlDatabase>
//#include <QSqlQueryModel>
#include <QTimer>
#include <QDateTime>
#include <QDebug>

#include "mysqlmodel.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void initWidget();

private slots:
    void slot_writeDataToDb();

    void on_cb_keepBottom_toggled(bool checked);
    void on_pb_start_clicked();
    void on_pb_stop_clicked();
    void on_pb_change_clicked();

private:
    Ui::MainWindow *ui;

    bool m_keepFlag;
    QTimer *m_timer;

    QSqlDatabase m_db;
    MySqlModel *m_model;
    MySqlModel *m_model2;

};
#endif // MAINWINDOW_H

5.mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    this->initWidget();
}

MainWindow::~MainWindow()
{
    delete ui;
    m_db.close();
}

//初始化界面
void MainWindow::initWidget()
{
    //初始化变量
    m_keepFlag = false;

    //以当天日期为名称创建数据库并打开
    QString dbPath = QCoreApplication::applicationDirPath() + "/SaveDbFile/";
    QString dbName = dbPath + QDate::currentDate().toString("yyyyMMdd") + ".db";
    m_db = QSqlDatabase::addDatabase("QSQLITE");
    m_db.setDatabaseName(dbName);
    if(!m_db.open())
    {
        //打开失败打印
        qDebug()<<"数据库打开失败..."<<m_db.lastError();
    }

    //创建名为dataTable的数据表
    QSqlQuery query(m_db);
    QString createStr = "create table if not exists dataTable(id integer primary key autoincrement, data varchar(30), time datetime)";
    query.exec(createStr);
    //创建名为dataTable2的数据表
    QString createStr2 = "create table if not exists dataTable2(id integer primary key autoincrement, test varchar(30), data varchar(30), time datetime)";
    query.exec(createStr2);

    //初始化表格模型
    m_model = new MySqlModel(this);
    QString initStr = "select * from dataTable;";   //获取dataTable表所有数据
    m_model->setQuery(initStr,m_db);
    while(m_model->canFetchMore())
    {
        m_model->fetchMore();   //为了显示全部数据,不然会出现只显示在256条数据的问题
    }
    m_model->setHeaderData(0,Qt::Horizontal,"序号");   //修改表名,不改的话与创建时的表名对应
    m_model->setHeaderData(1,Qt::Horizontal,"数据");
    m_model->setHeaderData(2,Qt::Horizontal,"时间");

    //初始化表格模型2
    m_model2 = new MySqlModel(this);
    QString initStr2 = "select * from dataTable2;";   //获取dataTable表所有数据
    m_model2->setQuery(initStr2,m_db);
    while(m_model2->canFetchMore())
    {
        m_model2->fetchMore();   //为了显示全部数据,不然会出现只显示在256条数据的问题
    }
    m_model2->setHeaderData(0,Qt::Horizontal,"序号");
    m_model2->setHeaderData(1,Qt::Horizontal,"测试");
    m_model2->setHeaderData(2,Qt::Horizontal,"数据");
    m_model2->setHeaderData(3,Qt::Horizontal,"时间");

    //设置表格属性,默认模型1
    ui->tableView->setModel(m_model);
    ui->tableView->horizontalHeader()->setStyleSheet("QHeaderView::section{background:white;color: black;}");   //区分列表头
    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);              //整行选中
    ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);             //单行选中
    ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);               //设置只读
    ui->tableView->verticalHeader()->hide();                                         //隐藏行头
    ui->tableView->verticalHeader()->setDefaultSectionSize(33);                      //设置行宽
    //ui->tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);   //自适应行宽
    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);   //自适应列度
    ui->tableView->setShowGrid(true);                                                //表格网格线显示
    ui->tableView->setGridStyle(Qt::SolidLine);                                      //网格线画笔
    ui->tableView->setFocusPolicy(Qt::NoFocus);                                      //去除选中时虚线框
    ui->tableView->scrollToBottom();                                                 //保持滚动条在底部

    // 初始化定时器
    m_timer = new QTimer(this);
    connect(m_timer,SIGNAL(timeout()),this,SLOT(slot_writeDataToDb()));
}

//定时器槽,写入数据
void MainWindow::slot_writeDataToDb()
{
    //获取当前时间和数据(这里模拟一个随机数)
    QString data = QString::number(qrand());
    QString time = QTime::currentTime().toString("hh:mm:ss");

    //插入数据
    QSqlQuery query(m_db);
    query.prepare("insert into dataTable(data,time) values(:data,:time)");   //插入数据
    query.bindValue(":data",data);
    query.bindValue(":time",time);
    query.exec();

    //更新表格模型
    QString initStr = "select * from dataTable;";
    m_model->setQuery(initStr,m_db);
    while(m_model->canFetchMore())
    {
        m_model->fetchMore();   //确保数据显示完全
    }

    //插入数据2
    QSqlQuery query2(m_db);
    query2.prepare("insert into dataTable2(test,data,time) values(:test,:data,:time)");   //插入数据
    query2.bindValue(":test","测试文本");
    query2.bindValue(":data",data);
    query2.bindValue(":time",time);
    query2.exec();

    //更新表格模型2
    QString initStr2 = "select * from dataTable2;";
    m_model2->setQuery(initStr2,m_db);
    while(m_model2->canFetchMore())
    {
        m_model2->fetchMore();   //确保数据显示完全
    }

    //保持滚动条在底部
    if(m_keepFlag)
    {
        ui->tableView->scrollToBottom();
    }
}

//保持底部勾选框
void MainWindow::on_cb_keepBottom_toggled(bool checked)
{
    m_keepFlag = checked;
}

//定时器开始
void MainWindow::on_pb_start_clicked()
{
    m_timer->start(1000);   // 每秒执行一次
}

//定时器停止
void MainWindow::on_pb_stop_clicked()
{
    m_timer->stop();
}

//切换数据表
void MainWindow::on_pb_change_clicked()
{
    static bool changeFlag = true;
    if(changeFlag)
    {
        changeFlag = false;
        ui->tableView->setModel(m_model2);
    }
    else
    {
        changeFlag = true;
        ui->tableView->setModel(m_model);
    }
    ui->tableView->scrollToBottom();
}

6.mainwindow.ui
请添加图片描述

四、下载链接

我的示例百度网盘链接:https://pan.baidu.com/s/17x9lUmWIWCvc8wJRw-5_jw
提取码:xxcj


总结

本文示例中会以当天日期为名称自动创建数据库,并在其中创建了两个数据表,界面上通过点击切换数据表按钮来更换模型刷新显示,其中使用了一个定时器来模拟数据插入库中的操作,并且将数据库的内容实时显示在界面上,表格上的数据文本居中是通过自定义MySqlModel类来实现的,这里的话只用到了Sqlite数据库的插入和查询语句,也是比较简单的,对这些语句的详细介绍可以查看参考文章。


hello:
共同学习,共同进步,如果还有相关问题,可在评论区留言进行讨论。

参考文章:
SQLite教程
五分钟教会你在Qt中使用SQLite数据库,非常有用,建议收藏!
QT6数据库操作—修改QSqlQueryModel完成QTableView的显示样式

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

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

相关文章

软件 工程

目录 第十章、软件工程1、瀑布模型&#xff08;SDLC&#xff09;2、快速原型模型3、增量模型4、螺旋模型5、Ⅴ模型6、喷泉模型7、构建组装模型&#xff08;CBSD&#xff09;8、统一过程&#xff08;RUP&#xff09;9、敏捷开发方法10、信息系统开发方法11、需求开发12、结构化设…

Codeforces Round 872 (Div. 2) 题解

总结&#xff1a;5.9有同学问B题&#xff0c;所以就连同ABC题一起做了&#xff0c;都算是思维题吧&#xff0c;难度不算高 A. LuoTianyi and the Palindrome String 思路&#xff1a;输入的都为回文字符串&#xff0c;如果输入的回文字符串每个字符都相同&#xff0c;如"…

QT+VS推箱子小游戏

1、创建一个GUI程序&#xff0c;将界面设计成如下样式&#xff1a; 创建一个已QDialog为基类的子类&#xff0c;在窗体里添加一个pushbutton的按钮&#xff0c;一个QLabel用来显示文字。窗体的背景图片和按钮的背景颜色&#xff0c;都可以在样式中进行设计。 2、右键项目名称&…

ChatGPT 实现云原生转型

云原生转型 在相对专业的细分领域&#xff0c;chatGPT 能起到什么作用呢&#xff1f;能给出什么回答&#xff0c;怎么问才能得到好的回答呢&#xff1f;本节内容&#xff0c;将尝试从一个业界其实也还没有定论的话题&#xff0c;开始问答。这就是&#xff1a;云原生转型。 &q…

OpenCV教程——图像模糊。均值模糊,高斯模糊,中值模糊,双边模糊,高斯分布

1.图像模糊 图像模糊是图像处理中最简单和常用的操作之一。 ⚠️使用该操作的原因之一是为了给图像预处理时降低噪声。 图像模糊操作背后是数学的卷积计算。 卷积操作的原理&#xff1a; 常用的图像模糊的方法&#xff1a; 均值模糊高斯模糊中值模糊双边模糊 这四种模糊方式…

商用密码应用安全性测评机构资质流程

商用密码应用安全性测评机构&#xff08;简称密评机构&#xff09;资质建设相关指导性材料包括&#xff1a; 1、《商用密码应用安全性测评机构能力要求》 2、《商用密码应用安全性测评机构能力评审实施细则&#xff08;试行&#xff09;》 3、《商用密码应用安全性测评机构管理…

【Rust】速度入门---打印个螃蟹先

参考: 菜鸟教程 1 输出到命令行 这不得打印个螃蟹 // 代码来自官方入门教程 // ferris_say需要另外安装 use ferris_says::say; use std::io::{stdout, BufWriter};fn main() {let stdout: std::io::Stdout stdout();let msg: String String::from("Hello fellow Rusta…

无线传感器网络的Z-SEP路由协议及对比(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 无线传感网络最早应用于军事领域&#xff0c;随着工业界和学术界的关注度提高和技术的成熟&#xff0c;现已广泛应用于军事侦查…

kubernetes❀集群环境搭建

kubernetes❀集群环境搭建 2. kubernetes集群环境搭建2.1 前置知识点2.2 kubeadm 部署方式介绍2.3 安装要求2.4 最终目标2.5 准备环境2.6 环境初始化2.6.1 检查操作系统的版本2.6.2 主机名解析2.6.3 时间同步2.6.4 禁用iptable和firewalld服务2.6.5 禁用selinux2.6.6 禁用swap分…

Rust Wasm Linux开发环境搭建

一、Linux 镜像版本 CentOS-7-x86_64-DVD-2009.iso&#xff0c;Virtual Box 7.0 选择 GNOME Desktop 版本&#xff0c; 配置远程连接&#xff08;可选&#xff09;&#xff0c; nmtui 激活连接 enp0s3 &#xff0c;查看 ip 地址&#xff0c; 绑定端口转发&#xff0c; 通过…

gateway与zuul的区别与联系

前言 zuul1.0与spring-cloud-gateway的区别 Zuul: zuul是netflix公司的项目&#xff0c;本质上是web servlet&#xff0c;基于JavaEE Servlet技术栈&#xff0c;使用阻塞API&#xff0c;处理的是http请求&#xff0c;没有提供异步支持&#xff0c;不支持任何长连接&#xff0c…

Linux——进程信号3

内核如何实现信号的捕捉 信号捕捉的方法出了我们之前的signal之外&#xff0c;还有其它方法 sigaction sigaction&#xff1a;检查或更改一个信号的动作即捕捉信号 第一个参数&#xff0c;要捕捉的信号对应的编号&#xff0c;第二个参数&#xff1a;结构体&#xff08;这个结构…

4种整流电路、5种滤波电路

目录 基本电路变压电路整流电路半波整流电路全波整流电路桥式整流电路倍压整流电路 滤波电路电容滤波电路电感滤波电路RC滤波电路LC滤波电路有源滤波电路 整流滤波电路总结常用整流电路性能对照常用无源滤波电路性能对照电容滤波电路输出电流大小与滤波电容量的关系常用整流滤波…

nodejs+vue大学招聘求职网站

该系统的基本功能包括学生注册登录&#xff0c;企业注册登录&#xff0c;发布个人简历&#xff0c;发布企业招聘信息&#xff0c;新闻资讯&#xff0c;招聘信息&#xff0c;企业管理&#xff0c;学生信息管理&#xff0c;招聘信息管理,修改密码等功能。 系统首页 后台界面 1.…

【设计模式】设计模式简述及类图

设计模式的分类依据两个准则&#xff0c;第一个是目的准则&#xff0c;即模式是用来完成什么工作的。模式依据其目的可以分为创建型、结构型和行为型三种。创建型模式和对象的创建有关&#xff0c;结构型模式处理类或对象的组合。行为型模式对类或对象怎样交互和怎样分配职责进…

随机变量X,分布函数X~F(x)的理解。

1.随机变量X 1.通常认知的"x"与随机变量X 我们通常意义上的 x 是自变量&#xff0c;y f(x) 中的自变量。 但是 X 更多意义是 对应法则 " f " &#xff0c;X完整写法是 X(ω) ω ∈ Ω。 X这个对应法则&#xff0c;可以将样本点映射到实数轴上。 那么X这…

初识linux之POSIX信号量

目录 一、信号量的概念 1. 信号量的作用 2. 信号量的PV操作 3. 信号量操作接口 3.1 初始化信号量 3.2 销毁信号量 3.3 等待信号量&#xff08;P操作&#xff09; 3.4 发布信号量&#xff08;V操作&#xff09; 二、循环队列 三、使用循环队列模拟实现生产消费模型 1…

Spring 组成及拓展

1. Spring 组成 1.1 Spring的七大模块 1.2拓展 在Spring官网有这个介绍&#xff1a;现代化的Java开发&#xff01;说白了就是基于Spring的开发 - SpringBoot - 一个快速开发的脚手架 - 基于SpringBoot可以快速的开发单个微服务。 - 约定大于配置&#xff01; - SpringC…

ENVI实现遥感图像的最小距离、最大似然、支持向量机分类

目录 1 分类需求 2 具体操作 2.1 ROI区域绘制 2.2 最小距离法 2.3 最大似然法 2.4 支持向量机 3 精度评定 4 分类后处理 4.1 小斑块处理 4.2 分类统计 4.3 修改类别颜色 5 结果对比 本文介绍基于ENVI软件&#xff0c;实现最小距离法、最大似然法与支持向量机三种遥…

达索的多领域系统级仿真软件Dymola 2023版本下载与安装配置教程

目录 前言一、Dymola 安装二、使用配置总结 前言 Dymola是由Dassault Systemes公司开发的一款基于物理建模的多领域系统级仿真软件。它包含了多个领域的建模和仿真工具&#xff0c;如机械、电气、液压、热力学、控制等&#xff0c;可以用于对各种系统进行建模和仿真&#xff0…