【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() {
    //连接第一个数据库
    //QMYSQL
    QSqlDatabase db = QSqlDatabase::addDatabase("QODBC", "connection1");//需要使用的数据库驱动和联检建立的名称(方便建立多个数据库连接【使用不同的数据库时】区分)
    db.setHostName("127.0.0.1");//连接地址
    db.setUserName("root");//数据库账户
    db.setPassword("55667788");//密码
    db.setPort(3306);//端口
    //test.db
    db.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_OBJECT

public:
	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);
}


四、效果展示

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

探索HTTP/2

文章目录 http/1.1http/2疑惑 探索1. 连接前言2. 帧结构2.1 帧类型 Type 3. 帧详情3.1 SETTINGS 帧3.2 WINDOW_UPDATE 帧3.3 PRIORITY 帧3.4 HEADERS 帧3.5 DATA 帧3.6 PING3.7 GOAWAY 帧3.8 RST_STREAM 帧3.9 PUSH_PROMISE 帧3.10 CONTINUATION 帧 你对http2了解多少&#xff…

BUUCTF--极客大挑战php

文章目录 1.网站备份文件www.zip2.下载后发现class.phpindex.phpflag.php 3.分析php代码绕过__wakeup方法变量权限为私有或保护python方法url方法 1.网站备份文件www.zip 2.下载后发现 class.php <?php include flag.php; error_reporting(0);class Name{private $usernam…

MYSQL5.7报1205 - Lock wait timeout exceeded; try restarting transaction

简介 今天使用navicate操作添加时&#xff0c;mysql报错误&#xff0c;错误如下 原因 这个问题的原因是在mysql中产生了事务A&#xff0c;执行了修改的语句&#xff0c;比如&#xff1a; update t1 set aget18 where id1;此时事务并未进行提交&#xff0c;事务B开始运行&am…

【C++精简版回顾】19.异常处理

1.throw抛出问题 int print(int a,int b) {if (b 0)throw b;return a / b; } 2.try与catch解决问题 try {print(2, 0); } catch (int b) {cout << "竟然是&#xff1a;"<<b<<endl; } 结果&#xff1a; 补充1&#xff1a;可以抛出字符串等 1.throw…

pytorch配置环境

1.查看cuda版本 nvidia-smi cuda version:12.3 2.下载torch 然后根据版本去查找对应的 torch下载代码 可查看这里&#xff1a;Previous PyTorch Versions | PyTorch 然后执行 conda install pytorch1.10.0 torchvision0.11.0 torchaudio0.10.0 cudatoolkit11.3 -c pytorch…

Python的文件操作

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 路在脚下&#xff0c;勇往直前&#x…

使用nvidia-ml-py事实监控GPU状态

平时监控GPU状态最常用的是watch配合nvidia-smi指令&#xff0c;但有时可能不仅仅需要监控&#xff0c;还需要记录状态数据&#xff0c;比如GPU的显存变化以及利用率变化等等。本文提供了一个使用nvidia-ml-py包编写的简易Demo&#xff0c;该Demo能够实现简易版的nvidia-smi功能…

[云原生] K8s之pod控制器详解

Pod 是 Kubernetes 集群中能够被创建和管理的最小部署单元。所以需要有工具去操作和管理它们的生命周期,这里就需要用到控制器了。 Pod 控制器由 master 的 kube-controller-manager 组件提供&#xff0c;常见的此类控制器有 Replication Controller、ReplicaSet、Deployment、…

openssl3.2 - exp - 产生随机数

文章目录 openssl3.2 - exp - 产生随机数概述笔记END openssl3.2 - exp - 产生随机数 概述 要用到openssl产生的随机数, 查了资料. 如果用命令行产生随机数, 如下: openssl rand -hex -num 6 48bfd3a64f54单步跟进去, 看到主要就是调用了一个RAND_bytes(), 没其他了. 官方说…

美国站群服务器使用技巧与注意事项

美国站群服务器使用技巧与注意事项有哪些?RAKsmart小编为您整理发布美国站群服务器使用技巧与注意事项&#xff0c;希望对您有帮助。 美国站群服务器的使用技巧主要包括远程管理、灵活配置和备份还原&#xff0c;具体如下&#xff1a; 1. **远程管理**&#xff1a;用户可以通过…

Promisification、微任务

前提摘要 Promise 对象的构造器&#xff08;constructor&#xff09;语法如下&#xff1a; let promise new Promise(function(resolve, reject) { // executor }); 传递给 new Promise的函数被称为 executor&#xff0c;当 new Promise 被创建&#xff0c;executor 会自动…

本地部署websocket服务端并结合内网穿透实现固定公网地址连接

文章目录 1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功,暴露端口默认99995. 创建隧道映射内网端口6. 查看状态->在线隧道,复制所创建隧道的公网地址加端口号7. 以…

So you think you understand IP fragmentation?

文章目录 前言一、Why care?二、Prevention三、Well-understood?四、Introducing fragquiz五、A novel (?) algorithm六、Reader challenge七、traceroute八、ICMP参考资料 前言 本文来自&#xff1a;https://lwn.net/Articles/960913/ February 7, 2024This article was …

英福康INFICON真空计VGC012-103-401使用说明

英福康INFICON真空计VGC012-103-401使用说明

【C++ Primer Plus学习记录】break和continue语句

break和continue语句都使程序能够跳过部分代码。可以在switch语句或任何循环中使用break语句&#xff0c;使程序跳到switch或循环后面的语句处执行。continue语句用于循环中&#xff0c;让程序跳过循环体中余下的代码&#xff0c;并开始新一轮循环&#xff08;参见图6.4&#x…

Unity性能优化篇(八) 导入的模型网格优化设置

模型导入Unity后&#xff0c;可以选中这个模型&#xff0c;在Inspector窗口设置它的属性。下面说的都是可自定义选择优化的地方 Model选择卡: 1.在Model选项卡&#xff0c;启用Mesh Compression可以压缩模型&#xff0c;压缩程度越高&#xff0c;模型精度越低&#xff0c;但是…

GEE 将裁剪后的Sentinel-2影像 在ArcGIS中去除空值

在ArcGIS中&#xff0c;可以使用栅格计算器&#xff08;Raster Calculator&#xff09;工具来设置NoData值为空。以下是在ArcGIS中将NoData值设置为空的步骤&#xff1a; 打开ArcGIS软件并加载下载的Sentinel-2影像数据。 影像Nodata空值以黑色背景呈现&#xff0c;影响矢量数据…

使用 Docker 部署 Stirling-PDF 多功能 PDF 工具

1&#xff09;Stirling-PDF 介绍 大家应该都有过这样的经历&#xff0c;面对一堆 PDF 文档&#xff0c;或者需要合并几个 PDF&#xff0c;或者需要将一份 PDF 文件拆分&#xff0c;又或者需要调整 PDF 中的页面顺序&#xff0c;找到的线上工具 要么广告满天飞&#xff0c;要么 …

OpenCV与机器学习:OpenCV实现主成分分析

OpenCV实现主成分分析 前言主成分分析&#xff08;PCA&#xff09;数据生成画图cv2.PCACompute绘制主成分分析结果 前言 维数灾难是指出现一定数量的特征&#xff08;或者维度&#xff09;后&#xff0c;分类器的性能将开始下降。特征越多&#xff0c;数据集中的信息就越多。但…

当前爆火的:ChatGPT4、Claude3、Gemini、Sora、GPTs及AI领域中的集中大模型的最新技术

原文链接&#xff1a;当前爆火的&#xff1a;ChatGPT4、Claude3、Gemini、Sora、GPTs及AI领域中的集中大模型的最新技术 第一&#xff1a;2024年AI领域最新技术 1.最新超强模型Claude3使用 2.OpenAI新模型-GPT-5 3.谷歌新模型-Gemini使用 4.Meta新模型-LLama3 5.阿里巴巴…