首页 > 其他分享 >Qt基础 | QSqIRelationalTableModel 的使用

Qt基础 | QSqIRelationalTableModel 的使用

时间:2024-07-25 12:53:58浏览次数:10  
标签:Qt void 基础 数据库 数据表 ui tabModel MainWindow QSqIRelationalTableModel

文章目录

关于QSqlDatabase、QSqIRelationalTableModel 、QSqlRecord类的使用可参考:Qt基础 | Qt SQL模块介绍 | Qt SQL模块常用类及其常用函数介绍

一、QSqIRelationalTableModel 的使用

  QSqIRelationalTableModel 可以处理关系数据表。所谓关系数据表,是指将主表里的某个字段存储为代码型字段,而代码字段的具体含义是在另一个数据表(代码表)里。QSqIRelationalTableModel 类专门用来编辑这种具有代码字段的数据表,可以很方便地将代码字段与关系数据表建立关系,在显示和编辑数据表时,直接使用关系表的代码意义字典的内容

1.主窗口MainWindow类定义

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include    <QMainWindow>

#include    <QLabel>
#include    <QString>

#include    <QtSql>
#include    <QDataWidgetMapper>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

private:
    QSqlDatabase  DB; //数据库连接
    QSqlRelationalTableModel  *tabModel;//数据模型
    QItemSelectionModel *theSelection;//选择模型

    void    openTable();//打开数据表
//    void    getFieldNames();//获取字段名称
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_currentChanged(const QModelIndex &current, const QModelIndex &previous);

    void on_actOpenDB_triggered();
    void on_actRecAppend_triggered();
    void on_actRecInsert_triggered();
    void on_actRevert_triggered();
    void on_actSubmit_triggered();
    void on_actRecDelete_triggered();
    void on_actFields_triggered();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

MainWindow 类中定义了几个私有变量:

  • QSqlDatabase DB:用于加载数据库驱动和建立与数据库之间的连接
  • QSqlRelationalTableModel *tabModel:用于指定某个数据表,作为数据表的数据模型,用来编辑关系数据表
  • QItemSelectionModel *theSelection:作为 tabModel的选择模型

函数:

  • openTable

槽函数:

  • on_currentChanged

2.构造函数

  MainWindow 的构造函数代码如下,主要是对 tableView 一些显示属性的设置。

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

    this->setCentralWidget(ui->tableView);

    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
    ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->tableView->setAlternatingRowColors(true);
}

3.打开数据表

  打开数据表这一部分主要包括:

  • 添加 SQLite 数据库驱动、设置数据库名称、打开数据库
  • 创建数据模型及其属性设置、选择模型、自定义代理组件、界面组件与模型数据字段间的数据映射

3.1 添加 SQLite 数据库驱动、设置数据库名称、打开数据库

  这一部分主要用到了 QSqlDatabase 类,该类用于处理与数据库的连接。

void MainWindow::on_actOpenDB_triggered()
{
    QString aFile=QFileDialog::getOpenFileName(this,"选择数据库文件","",
                             "SQL Lite数据库(*.db *.db3)");
    if (aFile.isEmpty())
       return;

//打开数据库
    DB=QSqlDatabase::addDatabase("QSQLITE"); //添加 SQL LITE数据库驱动
    DB.setDatabaseName(aFile); //设置数据库名称
//    DB.setHostName();
//    DB.setUserName();
//    DB.setPassword();
    if (!DB.open())   //打开数据库
    {
        QMessageBox::warning(this, "错误", "打开数据库失败",
                                 QMessageBox::Ok,QMessageBox::NoButton);
        return;
    }

//打开数据表
    openTable();
}

3.2 创建数据模型及其属性设置、选择模型、设置代码字段的查询关系数据表、为关系型字段设置缺省代理组件

  使用 QSqIRelationalTableModel 作为指定数据表的数据模型,用于显示与编辑关系数据表,并设置数据模型的属性。

tabModel=new QSqlRelationalTableModel(this,DB);
tabModel->setTable("studInfo"); //设置数据表
tabModel->setEditStrategy(QSqlTableModel::OnManualSubmit);  //OnManualSubmit , OnRowChange
tabModel->setSort(0,Qt::AscendingOrder);

  为字段设置显示标题

tabModel->setHeaderData(0,Qt::Horizontal,"学号");
tabModel->setHeaderData(1,Qt::Horizontal,"姓名");
tabModel->setHeaderData(2,Qt::Horizontal,"性别");
tabModel->setHeaderData(3,Qt::Horizontal,"学院");
tabModel->setHeaderData(4,Qt::Horizontal,"专业");

  设置代码字段的查询关系数据表

//设置代码字段的查询关系数据表
tabModel->setRelation(3,QSqlRelation("departments","departID","department")); //学院
tabModel->setRelation(4,QSqlRelation("majors","majorID","major"));//专业

  为数据模型创建一个选择模型,当选中的项发生变化时,选择模型发出currentChanged信号,其关联槽函数用于设置 “保存”和“取消” Action是否可用。

theSelection=new QItemSelectionModel(tabModel);
connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),
        this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));

槽函数:

void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous)
{//更新actPost和actCancel 的状态
    Q_UNUSED(current);
    Q_UNUSED(previous);
    ui->actSubmit->setEnabled(tabModel->isDirty()); //有未保存修改时可用
    ui->actRevert->setEnabled(tabModel->isDirty());
}

  为 tableView 设置数据模型与选择模型,为关系型字段设置缺省代理组件

ui->tableView->setModel(tabModel);
ui->tableView->setSelectionModel(theSelection);
ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView)); //为关系型字段设置缺省代理组件

  查询数据,并设置一些 Action 的使能状态。

tabModel->select(); //打开数据表

ui->actOpenDB->setEnabled(false);
ui->actRecAppend->setEnabled(true);
ui->actRecInsert->setEnabled(true);
ui->actRecDelete->setEnabled(true);
ui->actFields->setEnabled(true);

4.实际字段代码表

  使用 QSqIRelationalTableModel 类设置代码字段的查询关系后,在 tableView 中以代码意义显示代码字段的内容,其实际字段也发生了改变,变成了关系表中的代码意义字段。

void MainWindow::on_actFields_triggered()
{//获取字段列表
    QSqlRecord  emptyRec=tabModel->record();//获取空记录,只有字段名
    QString  str;
    for (int i=0;i<emptyRec.count();i++)
        str=str+emptyRec.fieldName(i)+'\n';

    QMessageBox::information(this, "所有字段名", str,
                             QMessageBox::Ok,QMessageBox::NoButton);
}

5.其他功能–添加、插入、删除、保存、取消

5.1 添加

  添加功能是在数据表的末尾添加一行记录,并设置选择模型的索引来选中刚插入的这一行

void MainWindow::on_actRecAppend_triggered()
{//添加记录
    tabModel->insertRow(tabModel->rowCount(),QModelIndex()); //在末尾添加一个记录
    QModelIndex curIndex=tabModel->index(tabModel->rowCount()-1,1);//创建最后一行的ModelIndex
    theSelection->clearSelection();//清空选择项
    theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);//设置刚插入的行为当前选择行
}

5.2 插入

  插入功能是在当前选中行的上一行插入一行,并选中刚插入的这一行。

void MainWindow::on_actRecInsert_triggered()
{//插入记录
    QModelIndex curIndex=ui->tableView->currentIndex();
    tabModel->insertRow(curIndex.row(),QModelIndex());

    theSelection->clearSelection();//清除已有选择
    theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
}

5.3 删除

  移除当前行并立即更新到数据库。

void MainWindow::on_actRecDelete_triggered()
{//删除当前记录
    tabModel->removeRow(theSelection->currentIndex().row());
    tabModel->submitAll(); //立即更新
}

5.4 保存

  保存功能即提交所有未更新的修改到数据库。

void MainWindow::on_actSubmit_triggered()
{//保存修改
    bool res=tabModel->submitAll();
    if (!res)
        QMessageBox::information(this, "消息", "数据保存错误,错误信息\n"+tabModel->lastError().text(),
                                 QMessageBox::Ok,QMessageBox::NoButton);
    else
    {
        ui->actSubmit->setEnabled(false);
        ui->actRevert->setEnabled(false);
    }
}

5.5 取消

  取消功能是取消所有未提交的修改。

void MainWindow::on_actRevert_triggered()
{//取消修改
    tabModel->revertAll();
    ui->actSubmit->setEnabled(false);
    ui->actRevert->setEnabled(false);
}

标签:Qt,void,基础,数据库,数据表,ui,tabModel,MainWindow,QSqIRelationalTableModel
From: https://blog.csdn.net/zwcslj/article/details/140686803

相关文章

  • Qt基础 | Qt SQL模块介绍 | Qt SQL模块常用类及其常用函数介绍
    文章目录一、QtSQL模块概述1.Qtsql支持的数据库2.SQLite数据库3.QtSQL模块的主要类一、QtSQL模块概述  QtSQL模块提供数据库编程的支持,Qt支持多种常见的数据库,如MySQL、Oracle、MSSQLServer、SQLite等。QtSQL模块包括多个类,可以实现数据库连接、SQ......
  • 错误 1 error LNK2019: 无法解析的外部符号 _MQTTClient_create,该符号在函数 "protect
    前言全局说明错误1errorLNK2019:无法解析的外部符号_MQTTClient_create,该符号在函数"protected:virtualint__thiscallCmfc_mqttclientpoweronoffDlg::OnInitDialog(void)"(?OnInitDialog@Cmfc_mqttclientpoweronoffDlg@@MAEHXZ)中被引用一、说明环境:Windows1......
  • go对接mqtt
    在Go语言中对接MQTT服务,你可以使用 paho.mqtt.golang 这个库,这是一个EclipsePahoMQTT客户端的Go语言实现。以下是一些基本步骤和示例代码,帮助你开始使用Go语言对接MQTT服务。1. 安装MQTT客户端库:使用Go的包管理器安装 paho.mqtt.golang 库:gogetgithub.com/eclipse/......
  • 计算机视觉基础:Harris角点检测算法手撕
    文章目录前言一、Harris角点检测是什么?二、算法原理1.角点及角点检测2.Harris角点检测原理3.角点的判别三、代码展示1.编程思路2.角点检测代码3.OpenCV接口调用四、可视化结果1.harris角点检测代码结果展示2.不同阈值和K值下角点检测结果比较五、实验总结前言本......
  • 2.1.1 通信基础的基本概念
    一、信源、信宿、信道、信号信源:信号的来源,数据的发送方。信宿:信号的“归宿”,数据的接收方。信道:信号的通道。一条物理线路通常包括两条信道,即为发送信道和接收信道。信号:数据的载体,信号又可以分为数字信号和模拟信号,数字信号的信号值是离散的,模拟信号的信号值是连续的。......
  • 适用于开发者的互联网基础架构服务API推荐
    ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20240702/1719891271764820771.png)在数字化时代,互联网基础架构服务构成了现代网络世界的支柱。从网站托管到云存储,再到网络安全,这些服务不仅支撑着全球网络的运行,也是推动创新和业务增长的关键因素。随着技术的不断演......
  • 六、【Python】基础教程-【Python全掌握】六大基础数据类型:浮点、布尔、列表、元组、
    ......
  • svelte - 1. 基础知识
    svelte中文官网vue和svelt语法对比掘金-svelte入门简介文章目录1、基本页面框架2、动态属性3、嵌套组件4、@html:插入html标签,显示真实dom元素5、点击事件on:click={handleClick}6、响应式声明7、父子组件通信8、if-else(1)if(2)if-else(3)if-elseif-......
  • pyqt5-网易云热歌列表爬取
    利用pyqt5实现网易云热歌列表爬取简单思路说明:利用QScrollArea滚动显示,QFlowLayout做布局,放置自定义的WidgetQNetworkAccessManager异步下载网页和图片QScrollArea滚动到底部触发下一页加载自定义控件说明:主要是多个layout和控件的结合,其中图片QLabel为自定义,通过setPixmap......
  • Docker简单使用、常用基础命令
    Docker简单使用、常用基础命令运行一个容器,输出helloworlddockerrunubuntu:laster/bin/echo"helloworld"docker:Docker的执行文件run:Docker的一个参数,作用是运行一个容器ubuntu:laster:指定要运行的镜像及版本,本地有直接运行,没有从镜像仓库下载运行/bin/echo"hello......