【QT C++实践】Qt 项目中一个界面动态处理多张数据库中的表|附源码
一、前言
在之前那篇讲如何使用QT连接数据库时(QT C++实践|超详细数据库的连接和增删改查操作|附源码),做了一个简单的对数据库进行增删改查的界面(如下)。
但是存在一个问题就是:这个界面只是对一张表进行操作,但是我们知道,一般数据库中都不止一张表,如果这个界面能够自由选择数据库中的表进行展示,和对其进行操作,岂不更好?
接下来我们就讲一下,如何基于上篇基础的对数据库中的表进行显示和操作,升级为可以自由选择数据库中的表,对其展示和操作!
二、思路
- 在UI界面添加一个QComboBox下拉框控件到页面,其中列出想要进行操作的数据库表名
- 连接这个QComboBox下拉框控件和currentIndexChanged信号到一个槽函数,在这个槽函数中更改当前模型的表名
- 当用户从下拉列表中选择一个表时,更新QSqlTableModel以反映所选表的数据。
三、源码
connection.h
#ifndef CONNECTION_H #define CONNECTION_H #include #include #include #include #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() 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(); }; 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); }
四、效果展示
有下拉框显示数据库中的不同表:
选择对应表,随即发生改变:
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。