【QT C++实践】Qt 项目中一个界面动态处理多张数据库中的表|附源码

一、前言

在之前那篇讲如何使用QT连接数据库时(QT C++实践|超详细数据库的连接和增删改查操作|附源码),做了一个简单的对数据库进行增删改查的界面(如下)。
在这里插入图片描述
但是存在一个问题就是:这个界面只是对一张表进行操作,但是我们知道,一般数据库中都不止一张表,如果这个界面能够自由选择数据库中的表进行展示,和对其进行操作,岂不更好?

接下来我们就讲一下,如何基于上篇基础的对数据库中的表进行显示和操作,升级为可以自由选择数据库中的表,对其展示和操作!

二、思路

  • 在UI界面添加一个QComboBox下拉框控件到页面,其中列出想要进行操作的数据库表名
  • 连接这个QComboBox下拉框控件和currentIndexChanged信号到一个槽函数,在这个槽函数中更改当前模型的表名
  • 当用户从下拉列表中选择一个表时,更新QSqlTableModel以反映所选表的数据。

三、源码

connection.h

#ifndef CONNECTION_H
#define CONNECTION_H#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>
#pragma execution_character_set("utf-8"); static bool createConnection() {//连接第一个数据库//QMYSQLQSqlDatabase db = QSqlDatabase::addDatabase("QODBC", "connection1");//需要使用的数据库驱动和联检建立的名称(方便建立多个数据库连接【使用不同的数据库时】区分)db.setHostName("127.0.0.1");//连接地址db.setUserName("root");//数据库账户db.setPassword("55667788");//密码db.setPort(3306);//端口//test.dbdb.setDatabaseName("windProject");//需要用到的数据库(ODBC中设置的名称if (!db.open()) {//如果数据库连接失败,则弹出//critical(QWidget *parent, const QString &title,//const QString &text,//QMessageBox::StandardButtons buttons = Ok,//QMessageBox::StandardButton defaultButton = NoButton)QMessageBox::critical(0, "Cannot open database","Unable to establish a database connection", QMessageBox::Cancel);return false;}else {QMessageBox::information(NULL, "infor", "link success");}
//    //下面来创建表
//    //如果MySQL数据库中已经存在同名的表,则下面代码不会执行
//    QSqlQuery query2(db);
//    
//   
//    // qDebug() << "connection2:";
创建表,并插入值
//    query2.exec("CREATE TABLE Construction ("
//        "id INT PRIMARY KEY,"
//        "ConstructionDate DATE,"
//        "ConstructionLocation VARCHAR(255),"
//        "WindTurbineModel VARCHAR(255))");
}#endif // CONNECTION_H

界面类Admin
Admin.h:

#pragma once#include <QMainWindow>
#include "ui_Admin.h"
#include <QSqlTableModel>
#include <QSqlDatabase>#pragma execution_character_set("utf-8"); class Admin : public QMainWindow
{Q_OBJECTpublic:Admin(QWidget *parent = nullptr);~Admin();//有关数据库操作的两个成员变量QSqlTableModel* model;//创建对象指针QSqlDatabase db;private:Ui::AdminClass ui;private slots:void on_add_clicked();void on_modify_clicked();void on_del_clicked();void on_rollback_clicked();void on_show_all_clicked();
};

Admin.cpp

#include "Admin.h"
#include <qmessagebox.h>
#include <QSqlDatabase>
#include <QMessageBox>
#include <qsqlerror.h>
#include "connection.h"
#include <QSqlTableModel>Admin::Admin(QWidget* parent): QMainWindow(parent)
{ui.setupUi(this);if (!createConnection()) {return;}db = QSqlDatabase::database("connection1");model = new QSqlTableModel(this, db);//由于在窗口的类中创建对象,因此实例化对象时,使用this指针(指向操作函数的指针)作为父对象// 假设您有一个QStringList来存放表名QStringList tableList = { "用户信息", "工地信息", "风电塔筒信息" ,"层级信息"}; // 这里填入您的表名ui.comboBox->addItems(tableList);//显示on_show_all_clicked();//当下拉框中的数据库的表的选项发生变换时,显示对应的表connect(ui.comboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(on_show_all_clicked()));//设置编辑策略model->setEditStrategy(QSqlTableModel::OnManualSubmit);//对所有模型改变立即用到数据库ui.tableView->setModel(model);
}Admin::~Admin()
{if (db.isOpen()) {db.close();}// 然后,从连接池中移除该连接QSqlDatabase::removeDatabase("connection1");
}// 添加记录按钮
void Admin::on_add_clicked()
{// 获得表的行数int rowNum = model->rowCount();int id = 10;// 添加一行model->insertRow(rowNum);model->setData(model->index(rowNum, 0), id);// 可以直接提交//model->submitAll();
}// 删除选中行按钮
void Admin::on_del_clicked()
{// 获取选中的行int curRow = ui.tableView->currentIndex().row();// 删除该行model->removeRow(curRow);int ok = QMessageBox::warning(this, tr("删除当前行!"),tr("你确定删除当前行吗?"), QMessageBox::Yes, QMessageBox::No);if (ok == QMessageBox::No){ // 如果不删除,则撤销model->revertAll();}else { // 否则提交,在数据库中删除该行model->submitAll();}}
// 撤销修改按钮
void Admin::on_rollback_clicked()
{model->revertAll();
}// 提交修改按钮
void Admin::on_modify_clicked()
{// 开始事务操作model->database().transaction();if (model->submitAll()) {if (model->database().commit()) // 提交QMessageBox::information(this, tr("tableModel"),tr("数据修改成功!"));}else {model->database().rollback(); // 回滚QMessageBox::warning(this, tr("tableModel"),tr("数据库错误: %1").arg(model->lastError().text()),QMessageBox::Ok);}
}
// 显示全表按钮
void Admin::on_show_all_clicked() {QString selectedTable = (ui.comboBox)->currentText();if (selectedTable == "用户信息") {selectedTable = "user";}else if (selectedTable == "工地信息") {selectedTable = "buildingsite";}else if (selectedTable == "风电塔筒信息") {selectedTable = "windtower";}else if (selectedTable == "层级信息") {selectedTable = "floor";}// 首先更改表和加载数据model->setTable(selectedTable);model->select();// 然后设置列标题if (selectedTable == "user") {// 设置显示名称,从0开始计数model->setHeaderData(0, Qt::Horizontal, tr("用户ID"));model->setHeaderData(1, Qt::Horizontal, tr("用户名称"));model->setHeaderData(2, Qt::Horizontal, tr("用户密码"));model->setHeaderData(3, Qt::Horizontal, tr("用户角色(1:管理员; 0:普通用户)"));}else if (selectedTable == "buildingsite") {// 设置显示名称,从0开始计数model->setHeaderData(0, Qt::Horizontal, tr("工地ID"));model->setHeaderData(1, Qt::Horizontal, tr("工地名称"));}else if (selectedTable == "windtower") {// 设置显示名称,从0开始计数model->setHeaderData(0, Qt::Horizontal, tr("塔筒ID"));model->setHeaderData(1, Qt::Horizontal, tr("所属工地ID"));model->setHeaderData(2, Qt::Horizontal, tr("塔筒层数"));}else if(selectedTable == "floor") {model->setHeaderData(0, Qt::Horizontal, tr("层级ID"));model->setHeaderData(1, Qt::Horizontal, tr("所属塔筒ID"));model->setHeaderData(2, Qt::Horizontal, tr("实际螺母个数"));model->setHeaderData(3, Qt::Horizontal, tr("检测螺母个数"));}(ui.tableView)->setModel(model);
}

四、效果展示

有下拉框显示数据库中的不同表:
在这里插入图片描述

选择对应表,随即发生改变:
在这里插入图片描述

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

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

相关文章

2023年CSP-J认证 CCF信息学奥赛C++ 中小学初级组 第一轮真题-选择题解析

2023年 中小学信息学奥赛CSP-J真题解析 1、在C中&#xff0c;下面哪个关键字用于声明一个变量&#xff0c;其值不能被修改 A、unsigned B、const C、static D、mutable 答案&#xff1a;B 考点分析&#xff1a;主要考查变量声明相关知识&#xff0c;const是声明常量&…

0基础跨考408|一战上岸复盘及经验分享

基础阶段‼️ 王道的四本书的选择题部分要都做完、订正完。 王道的四门视频课要一轮刷完&#xff08;或者题主在B站看了其他的老师&#xff0c;这其实也是算一轮的&#xff0c;只要题主是认真学习了的&#xff0c;题主说自己不知道看什么课&#xff0c;王道就好了&#xff09;…

Go程序是如何编译并运行起来的(图文详解)

Go程序是如何编译的 从hello RdrB1te开始 package main import "fmt" func main() { fmt.Println("hello RdrB1te") }不实际编译它&#xff0c;只输出它的编译过程&#xff1a; go build -n简单的编译过程分析&#xff1a; 上面的过程确认了两个…

Cookie和Session(会话技术)

文章目录 Cookie和Session&#xff08;会话技术&#xff09;一、Cookie1、Cookie概述1.1、Cookie简介1.2、Cookie的使用场景1.3、Cookie底层原理 2、Cookie的基本使用3、Cookie实现显示用户上次访问时间4、Cookie编码与解码5、Cookie总结 二、Session1、Session概述1.1、Sessio…

FPGA高端项目:FPGA基于GS2971的SDI视频接收+OSD动态字符叠加,提供1套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收转HDMI输出应用本方案的SDI接收图像缩放应用本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收HLS图像缩放HLS多路视频拼接应用本方案的SDI接收HLS多路视频融合叠加应用…

基于Matlab实现免疫荧光图像中的区域定位算法

基于Matlab实现免疫荧光图像中的区域定位算法 免疫荧光法。以荧光染料为标记物,试纸条为载体,发生抗原抗体特异性反应,根据免疫复合物被激发的荧光强度对待测物进行定量分析[。该方法具有环境要求不高、操作简单快速、无污染且荧光染料丰富等优点。 常用于食品安全检测过程中…

vue3+element plus 实现百度地图显示路径

添加依赖 <!-- index.html --><script type"text/javascript" src"//api.map.baidu.com/getscript?v3.0&akyI6kBeC9G4LntEWXklE2iNHwRUrmFEQc"></script><script type"text/javascript" src"//api.map.baidu.co…

【golang】26、retry-go 使用示例和源码解析

文章目录 一、使用方法1.1 http 示例1.1.1 retry.Do1.1.2 retry.DoWithData1.1.3 OnRetry1.1.4 根据 error 的类型&#xff0c;决定 delay 的时长1.1.5 自定义 retry function 二、API2.1 Do 执行2.1.1 Do2.1.2 DoWithData 2.2 Delay 策略2.3 错误处理2.3.1 Unwrap2.3.2 Unwrap…

idea手动导入插件

idea有时候连接不上 我们去手动下载压缩包 插件网址 选择下载的压缩包导入 导入成功

算力调度和云计算有何区别

Canalys发布的研究报告显示&#xff0c;2023年第二季度&#xff0c;全球云基础设施服务支出增长16%&#xff0c;达到724亿美元。 此前云厂商们的高速增长&#xff0c;主要归功于大规模的企业数字化转型和上云。当前市场的增速放缓&#xff0c;除了上云普及带来的市场增量见顶&…

centos7 部署kibana

先决条件参考 虚拟机部署elasticsearch集群-CSDN博客 这里使用elk101服务器安装kibana 下载rpm包(这里添加了-c参数用到wget的断点续传功能) #下载kibana-rpm包以及校验文件 wget -c https://artifacts.elastic.co/downloads/kibana/kibana-7.17.18-x86_64.rpm wget -c htt…

continue、break 和 return 的区别是什么?

continue、break和return同样是用于控制程序流程的关键字&#xff0c;它们有不同的作用和用法。 continue: 在Java中&#xff0c;continue语句同样通常用于循环结构&#xff08;如for循环、while循环&#xff09;。当程序执行到continue时&#xff0c;会立刻跳过当前循环中剩…

02_Git

文章目录 GitGit的核心流程Git的命令clone指令status指令add指令commit指令push指令pull指令log指令 Git中处理冲突协同合作Git中回退的措施忽略文件 Git git的特点&#xff1a; 分布式 比如说&#xff1a;同事A、同事B、同事C都能对远程仓库进行操作&#xff0c;就是分布式 …

微服务分布式中为什么要分库分表呢?

什么是分库分表&#xff1f; 概念&#xff1a; 分库分表是一种数据库水平扩展的方法&#xff0c;通过将数据分散存储在多个数据库实例或多张表中&#xff0c;以提高系统的性能和扩展性。在Java应用中&#xff0c;可以使用一些数据库中间件或框架来实现分库分表。 为什么要分…

pytorch什么是梯度

目录 1.导数、偏微分、梯度1.1 导数1.2 偏微分1.3 梯度 2. 通过梯度求极小值3. learning rate 1.导数、偏微分、梯度 1.1 导数 对于yx 2 2 2 的导数&#xff0c;描述了y随x值变化的一个变化趋势&#xff0c;导数是个标量反应的是变化的程度&#xff0c;标量的长度反应变化率的…

【嵌入式——QT】QTableWidget

表格小部件为应用程序提供标准的表格显示功能。QTableWidget中的项由QTableWidgetItem提供。 如果你想要一个使用你自己的数据模型的表&#xff0c;你应该使用QTableView而不是这个类。 常用函数 cellWidget(int row, int column) const&#xff1a;返回显示在给定行和列的单…

【Flutter 面试题】main()和runApp()函数在Flutter的作用分别是什么?有什么关系吗?

【Flutter 面试题】main()和runApp()函数在Flutter的作用分别是什么&#xff1f;有什么关系吗&#xff1f; 文章目录 写在前面解答补充说明 写在前面 关于我 &#xff0c;小雨青年 &#x1f449; CSDN博客专家&#xff0c;GitChat专栏作者&#xff0c;阿里云社区专家博主&…

论文研读_多目标部署优化:无人机在能源高效无线覆盖中的应用(ImMOGWO)精简版

此篇文章为Multi-objective Deployment Optimization of UAVs for Energy-Efficient Wireless Coverage的论文学习笔记&#xff0c;只供学习使用&#xff0c;不作商业用途&#xff0c;侵权删除。并且本人学术功底有限如果有思路不正确的地方欢迎批评指正! 创新点 RD算法 混合…

第十三届蓝桥杯嵌入式省赛程序设计详细题解

第十三届蓝桥杯嵌入式省赛题目相对于第十二届较为简单&#xff0c;没有那么多串口的数据处理以及判断&#xff01; 第十三届省赛主要是制作一个可由串口设置密码的密码锁。本实验中&#xff0c;我们将用到LED模块、按键模块、串口模块、定时器的PWM模块以及官方会提供源码的LC…

【HTML】HTML基础7.3(自定义列表)

目录 标签 效果 代码 注意 标签 <dl> <dt>自定义标题</dt><dd>内容1</dd><dd>内容2</dd><dd>内容3</dd> 。。。。。。 </dl> 效果 代码 <dl><dt>蜘蛛侠系列</dt><dd>蜘蛛侠1</dd…