一、前言
在之前那篇讲如何使用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);
}
四、效果展示
有下拉框显示数据库中的不同表:
选择对应表,随即发生改变: