Qt 数据库组件与TableView组件实现联动,以下案例中实现了,当用户点击并选中TableView组件内的某一行时,我们通过该行中的name字段查询并将查询结果关联到ListView组件内,同时将TableView中选中行的字段分别显示在窗体底部的LineEdit编辑内,该案例具体实现细节如下。

首先在UI界面中绘制好需要的控件,左侧放一个TableView组件,右侧是一个ListView组件,底部放三个LineEdit组件,界面如下:

我们还是需要创建两张表结构,表Student用于存储学生的基本信息,表StudentTimetable存储的是每个学生所需要学习的课程列表,执行后创建数据表。

void InitMultipleSQL()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("./lyshark.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)"
); // 批量创建数据
// https://www.cnblogs.com/lyshark
QStringList name_list; name_list << "lyshark" << "lisi" << "wangwu";
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 StudentTimetable");
db.exec("CREATE TABLE StudentTimetable("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name VARCHAR(40) NOT NULL, "
"timetable VARCHAR(128) NOT NULL"
")"); db.exec("INSERT INTO StudentTimetable(name,timetable) VALUES ('lyshark','AAA')");
db.exec("INSERT INTO StudentTimetable(name,timetable) VALUES ('lyshark','BBB')");
db.exec("INSERT INTO StudentTimetable(name,timetable) VALUES ('lyshark','CCC')"); db.exec("INSERT INTO StudentTimetable(name,timetable) VALUES ('lisi','QQQ')");
db.exec("INSERT INTO StudentTimetable(name,timetable) VALUES ('lisi','WWW')"); db.exec("INSERT INTO StudentTimetable(name,timetable) VALUES ('wangwu','EEE')"); db.commit();
db.close();
}

程序运行后,构造函数MainWindow::MainWindow(QWidget *parent)内初始化表格,查询Student表内记录,将查询到的指针绑定到theSelection模型上,绑定后再将绑定指针加入到dataMapper组件映射中,即可实现初始化,其初始化代码如下:

#include "mainwindow.h"
#include "ui_mainwindow.h" #include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlRecord>
#include <iostream>
#include <QStringList>
#include <QString>
#include <QVariant>
#include <QDataWidgetMapper>
#include <QtSql>
#include <QStandardItem>
#include <QStringList>
#include <QStringListModel> QSqlQueryModel *qryModel; // 数据模型
QItemSelectionModel *theSelection; // 选择模型
QDataWidgetMapper *dataMapper; // 数据界面映射 MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this); QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("./lyshark.db");
if (!db.open())
{
std::cout << db.lastError().text().toStdString()<< std::endl;
return;
} // 查询数据表中记录
qryModel=new QSqlQueryModel(this);
qryModel->setQuery("SELECT * FROM Student ORDER BY id");
if (qryModel->lastError().isValid())
{
return;
} // 设置TableView表头数据
qryModel->setHeaderData(0,Qt::Horizontal,"ID");
qryModel->setHeaderData(1,Qt::Horizontal,"Name");
qryModel->setHeaderData(2,Qt::Horizontal,"Age"); // 将数据绑定到模型上
theSelection=new QItemSelectionModel(qryModel);
ui->tableView->setModel(qryModel);
ui->tableView->setSelectionModel(theSelection);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); // 创建数据映射
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(); // 绑定信号,当鼠标选择时,在底部编辑框中输出
// https://www.cnblogs.com/lyshark
connect(theSelection,SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),this,SLOT(on_currentRowChanged(QModelIndex,QModelIndex)));
} MainWindow::~MainWindow()
{
delete ui;
}

此时这个程序运行后会得到表内数据:

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

  • 1.通过currentIndex方法获取到当前表所在行
  • 2.通过当前行号查询表中姓名,并带入StudentTimetable表查该表中记录
  • 3.循环获取该用户的数据,并将timetable字段提取出来放入QStringList容器
  • 4.将数据直接关联到ListView数据表中
// 鼠标点击后的处理槽函数
void MainWindow::on_currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{
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字段数据
int curRecNo=theSelection->currentIndex().row(); // 获取当前行号
QSqlRecord curRec=qryModel->record(curRecNo); // 获取当前记录
QString uname = curRec.value("name").toString();
std::cout << "Student Name = " << uname.toStdString() << std::endl; // 查StudentTimetable表中所有数据
// 根据姓名过滤出该用户的所有数据
QSqlQuery query;
query.prepare("select * from StudentTimetable where name = :x");
query.bindValue(":x",uname);
query.exec(); // 循环获取该用户的数据,并将timetable字段提取出来放入QStringList容器
// https://www.cnblogs.com/lyshark
QSqlRecord rec = query.record();
QStringList the_data; while(query.next())
{
int index = rec.indexOf("timetable");
QString data = query.value(index).toString(); std::cout << "User timetable = " << data.toStdString() << std::endl;
the_data.append(data);
} // 关联到ListView数据表中
QStringListModel *model;
model = new QStringListModel(the_data);
ui->listView->setModel(model);
ui->listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
}

当绑定选中事件时,程序运行效果如下:

针对底部按钮处理事件相对来说较为简单,其实现原理就是调用了TableView默认提供的一些函数而已,代码如下:

// 刷新tableView的当前选择行
// https://www.cnblogs.com/lyshark
void MainWindow::refreshTableView()
{
int index=dataMapper->currentIndex();
QModelIndex curIndex=qryModel->index(index,0); // 定位到低0行0列
theSelection->clearSelection(); // 清空选择项
theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);//设置刚插入的行为当前选择行
} // 第一条记录
void MainWindow::on_pushButton_clicked()
{
dataMapper->toFirst();
refreshTableView();
}
// 最后一条记录
void MainWindow::on_pushButton_2_clicked()
{
dataMapper->toLast();
refreshTableView();
} // 前一条记录
void MainWindow::on_pushButton_3_clicked()
{
dataMapper->toPrevious();
refreshTableView();
} // 下一条记录
void MainWindow::on_pushButton_4_clicked()
{
dataMapper->toNext();
refreshTableView();
}

最终运行效果如下所示:

C/C++ Qt 数据库与TableView多组件联动的更多相关文章

  1. C/C++ Qt 数据库与TreeView组件绑定

    在上一篇博文<C/C++ Qt 数据库QSql增删改查组件应用>介绍了Qt中如何使用SQL操作函数,并实现了对数据库的增删改查等基本功能,从本篇开始将实现数据库与View组件的绑定,通过数 ...

  2. C/C++ Qt 数据库与SqlTableModel组件应用

    SqlTableModel 组件可以将数据库中的特定字段动态显示在TableView表格组件中,通常设置QSqlTableModel类的变量作为数据模型后就可以显示数据表内容,界面组件中则通过QDat ...

  3. qt数据库多线程问题的解决(QSqlDatabase只能在创建它的线程中使用)

    Qt数据库由QSqlDatabase::addDatabase()生成的QSqlDatabase只能在创建它的线程中使用, 在多线程中共用连接或者在另外一个线程中创建query都是不支持的几乎国内没有 ...

  4. Qt添加驱动——Qt数据库之添加MySQL驱动插件

    Qt数据库之添加MySQL驱动插件(1) 现在可用的数据库驱动只有3种,在Qt中,我们需要自己编译其他数据库驱动的代码,让它们以插件的形式来使用.下面我们就以现在比较流行的MySQL数据库为例,说明一 ...

  5. Qt数据库_资料

    1. QT笔记_数据库总结(一)-rojian-ChinaUnix博客.html http://blog.chinaunix.net/uid-28194872-id-3631462.html (里面有 ...

  6. delphi完美经典-第16章 Delphi数据库程序设计----使用BDE组件

    第16章 Delphi数据库程序设计----使用BDE组件 Delphi访问数据库的方式有:ADO.BDE.dbExpress.InterBase Express. 一.TDataSet组件 虽然De ...

  7. Qt高仿Excel表格组件-支持冻结列、冻结行、内容自适应和合并单元格

    目录 一.概述 二.效果展示 三.实现思路 1.冻结行.冻结列 2.行高自适应 3.蚂蚁线 四.测试代码 1.添加表格数据 2.设置冻结行.列 3.行高.列宽 4.单元格背景色 5.单元格文字 6.其 ...

  8. Qt数据库 QSqlTableModel实例操作(转)

    本文介绍的是Qt数据库 QSqlTableModel实例操作,详细操作请先来看内容.与上篇内容衔接着,不顾本文也有关于上篇内容的链接. Qt数据库 QSqlTableModel实例操作是本文所介绍的内 ...

  9. 第15.10节 PyQt(Python+Qt)入门学习:Qt Designer可视化设计界面组件与QWidget类相关的组件属性详解

    PyQt学习有阵子了,对章节的骨架基本考虑好了,准备本节就写组件的属性的,结果一是日常工作繁忙,经常晚上还要加班,二是Qt的组件属性很多,只能逐一学习.研究和整理,花的时间有点长,不过终于将可视化设计 ...

随机推荐

  1. linux下软链接文件的拷贝

    最近在编译libnl库准备拷贝到其他机器中使用的时候出现无法拷贝问题,原因是sd卡是fat32文件系统格式,这种文件系统不支持linux下的ln软链接文件, void@void-ThinkPad-E4 ...

  2. 挂载nfs存储

    查看nfs服务器上提供了哪些nfs目录 showmount -e 172.16.3.8 使用showmount前需要安装nfs-utils包 yum install nfs-utils -y 挂载nf ...

  3. ICMP 协议仿真及ping命令用途

    1.实验目的 加深对 IPv4 协议首部各定义域的理解,掌握路由表的结构和基本配置命令,熟悉 ICMP 的调试操作. 2.实验原理 IPv4 协议定义,网络层协议的相关 RFC 定义和描述. 3.实验 ...

  4. 使用 SSL 加密的 JDBC 连接 SAP HANA 数据库

    近期客户为满足安全要求,提了让业务应用使用 SSL 方式连接 SAP HANA 数据库的需求.本人查询 SAP官方文档 发现数据库支持 SSL 连接,有参数直接加到 JDBC 的 URL 后边就行了, ...

  5. Nginx面试题(总结最全面的面试题!!!)

    https://blog.csdn.net/weixin_43122090/article/details/105461971

  6. pytest-mian函数运行

    1.设置多并发运行 1.命令行安装 pip install pytest-xdist #安装插件,进行多并发运行,#调用:-n -5 import pytest # pytest.main([&quo ...

  7. int,double与机器字长

    机器字长:计算机能直接处理的二进制数据的位数,它决定了计算机的运算精度想深入了解. 学好汇编语言对你帮助非常大.汇编语言中的,最基本的数据类型有: (1) byte (2)word (3)double ...

  8. [gym102978D]Do Use FFT

    前置知识 (以下内容并不严谨,可以参考论文<转置原理的简单介绍>) 对于一个算法,其为线性算法当且仅当仅包含以下操作: 1.$read\ i$,将$r_{i}$的值赋为(下一个)读入的元素 ...

  9. [hdu6995]Travel on Tree

    问题即查询将其按照dfs序排序后,相邻两点(包括首尾)的距离和 考虑使用莫队+set维护,时间复杂度为$o(n\sqrt{n}\log n)$,无法通过 进一步的,注意到删除是可以用链表实现的,因此考 ...

  10. [bzoj1077]天平

    先考虑如何求出任意两数的最大差值和最小差值,直接差分约束建图跑floyd求最短路和最长路即可然后枚举i和j,考虑dA+dB和di+dj的关系,分两种情况移项,转化成dA-di和dj-dB的关系或dA- ...