C++ Qt开发:数据库与TableView多组件联动

这篇具有很好参考价值的文章主要介绍了C++ Qt开发:数据库与TableView多组件联动。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍TableView组件与数据库联动的常用方法及灵活运用。

在Qt中,通常我们不会在TableView等组件中保存数据,一般会将这些数据存储至数据库或者是文件中保存,当使用时则动态的在数据库中调出来,以下案例将实现,当用户点击并选中TableView组件内的某一行时,我们通过该行中的name字段查询,并将查询结果关联到ListView组件内,同时将TableView中选中行的字段分别显示在窗体底部的LineEdit编辑框内。

要实现联动涉及几个主要步骤:建立数据库连接、创建模型、设置TableView、捕捉TableView的选中信号、查询并关联数据、更新LineEditListView,首先我们在UI界面中绘制所需控件,如下图左侧放一个TableView组件,右侧是一个ListView组件,底部放三个LineEdit组件;

C++ Qt开发:数据库与TableView多组件联动

接着我们需要创建两张数据表,其中Student表主要用来存储学生信息,而StudentAddressList用于存储学生所管理的IP地址,我们将表中的name进行关联,每个学生名下存储有不同的地址;

C++ Qt开发:数据库与TableView多组件联动

创建两个表结构总结起来代码如下所示,通过分别调用多次db.exec()函数实现创建数据表,并通过QSqlQuery类实现批量插入数据集;

void InitMultipleSQL()
{
    // ----------------------------------------------
    // 初始化表结构
    // ----------------------------------------------
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("./database.db");
     if (!db.open())
     {
            std::cout << db.lastError().text().toStdString()<< std::endl;
            return;
     }

    // 执行SQL创建表
    db.exec("DROP TABLE Student");
    db.exec("CREATE TABLE Student ("
                    "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                    "name VARCHAR(40) NOT NULL, "
                    "age INTEGER NOT NULL)"
         );

    // 批量创建数据
    QStringList name_list; name_list << "lyshark" << "admin" << "guest";
    QStringList age_list; age_list << "25" << "34" << "45";

    // 绑定并插入数据
    QSqlQuery query;
    query.prepare("INSERT INTO Student(name,age) ""VALUES (:name, :age)");

    if(name_list.size() == age_list.size())
    {
        for(int x=0;x< name_list.size();x++)
        {
            query.bindValue(":name",name_list[x]);
            query.bindValue(":age",age_list[x]);
            query.exec();
        }
    }

    // ----------------------------------------------
    // 创建第二张表
    // ----------------------------------------------
    // 与第一张表通过姓名关联起来
    db.exec("DROP TABLE StudentAddressList");
    db.exec("CREATE TABLE StudentAddressList("
            "id INTEGER PRIMARY KEY AUTOINCREMENT, "
            "name VARCHAR(40) NOT NULL, "
            "address VARCHAR(128) NOT NULL"
            ")");

    // 插入数据
    db.exec("INSERT INTO StudentAddressList(name,address) VALUES ('lyshark','192.168.1.1')");
    db.exec("INSERT INTO StudentAddressList(name,address) VALUES ('lyshark','192.168.1.2')");
    db.exec("INSERT INTO StudentAddressList(name,address) VALUES ('lyshark','192.168.1.3')");
    db.exec("INSERT INTO StudentAddressList(name,address) VALUES ('admin','192.168.10.10')");
    db.exec("INSERT INTO StudentAddressList(name,address) VALUES ('admin','192.168.10.11')");
    db.exec("INSERT INTO StudentAddressList(name,address) VALUES ('guest','192.168.100.100')");
}

1.1 初始化组件

接着我们需要在构造函数MainWindow::MainWindow(QWidget *parent)内初始化``TableView表格,查询Student表内记录,将查询到的指针绑定到theSelection模型上,绑定后再将绑定指针加入到dataMapper组件映射中,即可实现初始化,这里有必要介绍一下QSqlQueryModelQItemSelectionModelQDataWidgetMapper`这三个模型类。

QSqlQueryModel

用于与数据库交互的模型类之一,它继承自 QAbstractTableModelQSqlQueryModel 通过执行 SQL 查询语句,将查询结果作为表格数据提供给 Qt 的视图组件,如 QTableView等。

以下是 QSqlQueryModel 的一些常用方法,概述成表格形式:

方法 描述
setQuery(const QString &query, const QSqlDatabase &db = QSqlDatabase()) 设置要执行的 SQL 查询和数据库连接。查询执行后,结果将被提供给模型。
clear() 清除模型中的数据。
lastError() const 返回最后一次执行的查询的错误。
record() const 返回包含查询结果字段信息的 QSqlRecord 对象。
data(const QModelIndex &item, int role = Qt::DisplayRole) const 返回与给定索引处的项相关联的数据,用于提供给视图请求的数据。
rowCount(const QModelIndex &parent = QModelIndex()) const 返回模型中的行数。
columnCount(const QModelIndex &parent = QModelIndex()) const 返回模型中的列数。

上述方法提供了一般性的查询执行、错误处理、结果处理等功能,使得通过 QSqlQueryModel 能够方便地将数据库中的查询结果集与 Qt 的视图组件进行关联。使用这些方法,你可以在应用中执行 SQL 查询,并将结果显示在相应的视图组件中。

QItemSelectionModel

用于管理项选择的模型类,它是 QAbstractItemModel 类的衍生类。QItemSelectionModel 用于追踪一个或多个视图中的选择项,同时允许对这些选择项进行查询和修改。

以下是 QItemSelectionModel 的一些常用方法,概述成表格形式:

方法 描述
QItemSelectionModel(QAbstractItemModel *model) 构造函数,创建一个选择模型并关联指定的数据模型。
setModel(QAbstractItemModel *model) 设置关联的数据模型。
model() const 返回与此选择模型相关联的数据模型。
currentIndex() const 返回当前焦点的项的索引。
selectedIndexes() const 返回当前选择的项的索引列表。
clear() 清除模型中的所有选择项。
select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) 根据给定的 QModelIndex 对象和选择标志执行选择操作。
select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) 根据给定的 QItemSelection 对象和选择标志执行选择操作。
reset() 重置选择模型,清除所有选择和当前索引。
setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) 设置当前焦点项。
currentIndexChanged(const QModelIndex &current, const QModelIndex &previous) 当前焦点项变化时发出的信号。
selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) 选择发生变化时发出的信号。

这些方法允许你在一个或多个视图中管理选择项,进行选择的查询、修改,以及处理选择变化的信号。通过使用这些方法,你可以实现对模型中的项进行灵活的选择操作,并及时响应选择的变化。

QDataWidgetMapper

用于实现数据和小部件之间双向映射的类,使得数据模型的变化能够反映在界面上,同时用户界面的修改也能够同步到数据模型中。

以下是 QDataWidgetMapper 的一些主要方法,概述成表格形式:

方法 描述
QDataWidgetMapper(QObject *parent = nullptr) 构造函数,创建一个数据映射器对象。
setModel(QAbstractItemModel *model) 设置映射的数据模型。
model() const 返回与此数据映射器相关联的数据模型。
addMapping(QWidget *widget, int section) 将指定的小部件和数据模型的字段进行映射。
removeMapping(QWidget *widget) 移除与指定小部件的映射关系。
mappedWidgetAt(int section) const 返回与数据模型的指定字段映射的小部件。
mappedSection(QWidget *widget) const 返回与指定小部件映射的数据模型字段的索引。
setCurrentIndex(int index) 将映射的数据移动到指定的索引。
currentIndex() const 返回当前映射的数据的索引。
toFirst(), toLast(), toNext(), toPrevious() 分别将映射的数据移动到第一行、最后一行、下一行、上一行。
submit() 将界面上的更改提交到模型。
revert() 撤销所有未提交的更改。
setSubmitPolicy(QDataWidgetMapper::SubmitPolicy policy) 设置更改提交策略。
submitPolicy() const 返回当前的更改提交策略。
addMapping(QWidget *widget, int section, const QByteArray &propertyName) 将小部件和数据模型字段以及小部件属性进行映射。
toFirst(), toLast(), toNext(), toPrevious() 分别将映射的数据移动到第一行、最后一行、下一行、上一行。

这些方法使得在 Qt 应用程序中更容易实现数据模型和用户界面的交互,通过将数据模型字段映射到用户界面的小部件上,实现了数据的显示和编辑的同步。通过调用 setCurrentIndextoNexttoPrevious 等方法,你可以在数据模型中移动,并自动更新映射的小部件上显示的数据。最后,通过调用 submit 将界面上的更改提交到模型,而 revert 则撤销未提交的更改。

初始化UI界面很容易实现,首席按初始化表结构,通过调用封装好的InitMultipleSQL可以直接初始化并将数据保存至database.db文件中,在主程序中我们一次执行如下操作来实现数据的初始化与展现。

打开数据库

使用 SQLite 数据库,并尝试打开名为 "database.db" 的数据库文件。如果打开失败,将输出错误信息并返回。需要注意确保数据库文件存在且可访问。

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("./database.db");
if (!db.open())
{
    std::cout << db.lastError().text().toStdString()<< std::endl;
    return;
}

查询数据表中记录

通过 QSqlQueryModel 查询 Student 表中的所有记录,并按 id 排序。如果查询过程中出现错误,需要处理错误。

qryModel=new QSqlQueryModel(this);
qryModel->setQuery("SELECT * FROM Student ORDER BY id");

设置 TableView 表头数据

设置查询模型的表头数据,分别为 "ID"、"Name"、"Age"。

qryModel->setHeaderData(0,Qt::Horizontal,"ID");
qryModel->setHeaderData(1,Qt::Horizontal,"Name");
qryModel->setHeaderData(2,Qt::Horizontal,"Age");

绑定数据到模型和 TableView

创建一个 QItemSelectionModel 对象 theSelection,并将其绑定到查询模型 qryModel 上。然后将模型和选择模型分别绑定到 ui->tableView 上,设置选择行为为按行选择。

theSelection=new QItemSelectionModel(qryModel);
ui->tableView->setModel(qryModel);
ui->tableView->setSelectionModel(theSelection);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);

创建数据映射器 QDataWidgetMapper

创建 QDataWidgetMapper 对象 dataMapper,设置提交策略为自动提交。然后将映射器和模型绑定,并将三个文本框小部件与模型的相应字段进行映射。最后,将映射器移动到第一行。

dataMapper= new QDataWidgetMapper();
dataMapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);
dataMapper->setModel(qryModel);
dataMapper->addMapping(ui->lineEdit_id,0);
dataMapper->addMapping(ui->lineEdit_name,1);
dataMapper->addMapping(ui->lineEdit_age,2);
dataMapper->toFirst();

绑定信号

连接 theSelectioncurrentRowChanged 信号到槽函数 on_currentRowChanged。这样,当用户在表格中选择不同行时,将触发槽函数执行相应的操作。

connect(theSelection,SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
        this,SLOT(on_currentRowChanged(QModelIndex,QModelIndex)));

上述代码实现了组件初始化,使用数据库表格中的数据填充了一个 QTableView,并通过 QDataWidgetMapper 将选中行的数据映射到三个文本框中,同时通过信号槽机制实现了在底部编辑框中显示当前选中行的功能。

1.2 绑定事件

接着我们需要绑定TableView表格的on_currentRowChanged()事件,当用户点击TableView表格中的某个属性时则自动触发该函数,在此函数内我们完成对其他组件的填充,如下是对绑定事件的具体分析。

如下这部分代码使用了 Q_UNUSED 宏,用于标记 previous 未使用,以避免编译器产生未使用变量的警告。接着判断 current 是否有效,如果无效则直接返回,避免出现错误。

Q_UNUSED(previous);
if (!current.isValid())
{
    return;
}

dataMapper->setCurrentModelIndex(current);

这段代码判断当前行是否为表格的第一行或最后一行,并输出相应的信息。

// 获取到记录开头结尾
bool first=(current.row()==0);                    // 是否首记录
bool last=(current.row()==qryModel->rowCount()-1);// 是否尾记录
std::cout << "IsFirst: " << first << "IsLast: " << last << std::endl;

获取当前选择行的 name 字段的数据,并输出到标准输出流。

// 获取name字段数据
int curRecNo=theSelection->currentIndex().row();  // 获取当前行号
QSqlRecord curRec=qryModel->record(curRecNo);     // 获取当前记录
QString uname = curRec.value("name").toString();
std::cout << "Student Name = " << uname.toStdString() << std::endl;

代码查询名为 StudentAddressList 的表中与当前用户名匹配的所有数据,并将 address 字段的数据提取出来存储在 the_data 容器中。

// 查StudentAddressList表中所有数据
// 根据姓名过滤出该用户的所有数据
QSqlQuery query;
query.prepare("select * from StudentAddressList where name = :x");
query.bindValue(":x",uname);
query.exec();

// 循环获取该用户的数据,并将address字段提取出来放入QStringList容器
QSqlRecord rec = query.record();
QStringList the_data;

while(query.next())
{
    int index = rec.indexOf("address");
    QString data = query.value(index).toString();

    std::cout << "User Address = " << data.toStdString() << std::endl;
    the_data.append(data);
}

最后,将 the_data 中的数据关联到 QListView 控件上,并设置为不可编辑。这样,用户就可以在 QListView 中看到与当前表格行对应的地址信息。

// 关联到ListView数据表中
QStringListModel *model;
model = new QStringListModel(the_data);
ui->listView->setModel(model);
ui->listView->setEditTriggers(QAbstractItemView::NoEditTriggers);

至此核心功能的实现就结束了,通过对信号的绑定,当读者运行程序并选中TableView组件中的任意一行是,其右侧ListView与底部的LineEdit编辑框均会实现联动效果,如下图所示;

C++ Qt开发:数据库与TableView多组件联动文章来源地址https://www.toymoban.com/news/detail-760414.html

到了这里,关于C++ Qt开发:数据库与TableView多组件联动的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • QT学习笔记-开发环境编译Qt MySql数据库驱动与交叉编译Qt MySql数据库驱动

    如果需要在QT程序中实现与MySQL数据库的交互,那么必不可少的一环就是对Qt MySql数据库驱动的编译。 操作系统:Windows10 专业版 64位 Qt版本:Qt 5.15.2 开发环境Qt安装路径:D:Qt 交叉编译服务器:Ubuntu 18.4 交叉编译服务器Qt安装路径:/opt/Qt 目标芯片:rk3568 目标平台:arm64 Qt安装

    2024年02月11日
    浏览(78)
  • C++ Qt开发:StandardItemModel数据模型组件

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍 StandardItemModel 数据模型组件的常用方法及灵活运用。 QStandardItemModel 是 Qt 中用

    2024年02月04日
    浏览(48)
  • 软件设计开发笔记4:QT操作SQLite数据库

      有时候我们需要在软件中记录一些历史数据以便于对数据的查询。而我们希望软件不能太复杂,体量也不要太大,这个时候就需要如SQLite这样轻量级的数据库。这篇中我们就来讨论如何在使用QT开发应用是操作SQLite数据库。   SQLite是一款开源、轻量级、跨平台的数据库

    2024年02月09日
    浏览(65)
  • Qt 之tableView控件C++语言

    table view是用的比较多的一个控件之一,我们在展示数据或者表格的时候经常用到。 1、添加表头 2、 添加行数据 3、 获取双击事件 4、获取选中行内容 5、删除行 以上就是QT中TABLE VIEW的使用,其实还有很多属性可以设置,比如是否隐藏表头呀,是否显示网格线呀,QSS样式设置

    2024年02月13日
    浏览(42)
  • C++毕业设计基于QT实现的超市收银管理系统源代码+数据库

    C++毕业设计基于QT实现的超市收银管理系统源代码+数据库 编译使用 编译完成后,需要拷贝 file目录下的数据库 POP.db文件到可执行程序目录下 登录界面 主界面 会员管理 完整代码下载地址:基于QT实现的超市收银管理系统源代码+数据库

    2024年02月09日
    浏览(63)
  • 跨平台C++ Qt数据库管理系统设计与实战:从理论到实践的全面解析

    在我们的日常生活中,数据无处不在。无论是我们的个人信息,还是我们的购物习惯,甚至是我们的工作记录,都可以被视为数据。这些数据的管理和处理,对于个人和企业来说,都是至关重要的。这就是数据库管理系统(Database Management System,简称DBMS)的重要性所在。 数据

    2024年02月06日
    浏览(66)
  • QT学习笔记-oracle oci数据库驱动交叉编译并移植到ARM开发板

    在上一文《QT学习笔记-QT安装oracle oci驱动》中介绍了在Windows环境下使用QT访问oracle数据库时遇到驱动无法加载问题的解决办法,大体思路是对QT源码中数据库驱动的源码oci进行编译,要想通过编译需要依赖对应数据库的头文件和库(可以通过下载oracle instant client),编译通过

    2024年02月13日
    浏览(57)
  • QT中TableView数据展示

    最近在学习QT,大量数据从数据库取出放入QT界面中展示,这时用到了tableView,一些简单的使用分享给大家。 QStandardItemModel是Qt库中的一个类,它是QAbstractItemModel的一个子类。它可以用来存储和管理数据,并且可以通过Qt视图类(如QListView、QTreeView等)来显示这些数据。

    2024年02月11日
    浏览(43)
  • Qt+MySql开发笔记:Qt5.9.3的msvc2017x64版本编译MySql8.0.16版本驱动并Demo连接数据库测试

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130381428 红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…   mysql驱动版本msvc2015x32版本调

    2023年04月26日
    浏览(87)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包