C/C++ Qt 数据库与TableView多组件联动
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 ¤t, 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多组件联动的更多相关文章
- C/C++ Qt 数据库与TreeView组件绑定
在上一篇博文<C/C++ Qt 数据库QSql增删改查组件应用>介绍了Qt中如何使用SQL操作函数,并实现了对数据库的增删改查等基本功能,从本篇开始将实现数据库与View组件的绑定,通过数 ...
- C/C++ Qt 数据库与SqlTableModel组件应用
SqlTableModel 组件可以将数据库中的特定字段动态显示在TableView表格组件中,通常设置QSqlTableModel类的变量作为数据模型后就可以显示数据表内容,界面组件中则通过QDat ...
- qt数据库多线程问题的解决(QSqlDatabase只能在创建它的线程中使用)
Qt数据库由QSqlDatabase::addDatabase()生成的QSqlDatabase只能在创建它的线程中使用, 在多线程中共用连接或者在另外一个线程中创建query都是不支持的几乎国内没有 ...
- Qt添加驱动——Qt数据库之添加MySQL驱动插件
Qt数据库之添加MySQL驱动插件(1) 现在可用的数据库驱动只有3种,在Qt中,我们需要自己编译其他数据库驱动的代码,让它们以插件的形式来使用.下面我们就以现在比较流行的MySQL数据库为例,说明一 ...
- Qt数据库_资料
1. QT笔记_数据库总结(一)-rojian-ChinaUnix博客.html http://blog.chinaunix.net/uid-28194872-id-3631462.html (里面有 ...
- delphi完美经典-第16章 Delphi数据库程序设计----使用BDE组件
第16章 Delphi数据库程序设计----使用BDE组件 Delphi访问数据库的方式有:ADO.BDE.dbExpress.InterBase Express. 一.TDataSet组件 虽然De ...
- Qt高仿Excel表格组件-支持冻结列、冻结行、内容自适应和合并单元格
目录 一.概述 二.效果展示 三.实现思路 1.冻结行.冻结列 2.行高自适应 3.蚂蚁线 四.测试代码 1.添加表格数据 2.设置冻结行.列 3.行高.列宽 4.单元格背景色 5.单元格文字 6.其 ...
- Qt数据库 QSqlTableModel实例操作(转)
本文介绍的是Qt数据库 QSqlTableModel实例操作,详细操作请先来看内容.与上篇内容衔接着,不顾本文也有关于上篇内容的链接. Qt数据库 QSqlTableModel实例操作是本文所介绍的内 ...
- 第15.10节 PyQt(Python+Qt)入门学习:Qt Designer可视化设计界面组件与QWidget类相关的组件属性详解
PyQt学习有阵子了,对章节的骨架基本考虑好了,准备本节就写组件的属性的,结果一是日常工作繁忙,经常晚上还要加班,二是Qt的组件属性很多,只能逐一学习.研究和整理,花的时间有点长,不过终于将可视化设计 ...
随机推荐
- linux下软链接文件的拷贝
最近在编译libnl库准备拷贝到其他机器中使用的时候出现无法拷贝问题,原因是sd卡是fat32文件系统格式,这种文件系统不支持linux下的ln软链接文件, void@void-ThinkPad-E4 ...
- 挂载nfs存储
查看nfs服务器上提供了哪些nfs目录 showmount -e 172.16.3.8 使用showmount前需要安装nfs-utils包 yum install nfs-utils -y 挂载nf ...
- ICMP 协议仿真及ping命令用途
1.实验目的 加深对 IPv4 协议首部各定义域的理解,掌握路由表的结构和基本配置命令,熟悉 ICMP 的调试操作. 2.实验原理 IPv4 协议定义,网络层协议的相关 RFC 定义和描述. 3.实验 ...
- 使用 SSL 加密的 JDBC 连接 SAP HANA 数据库
近期客户为满足安全要求,提了让业务应用使用 SSL 方式连接 SAP HANA 数据库的需求.本人查询 SAP官方文档 发现数据库支持 SSL 连接,有参数直接加到 JDBC 的 URL 后边就行了, ...
- Nginx面试题(总结最全面的面试题!!!)
https://blog.csdn.net/weixin_43122090/article/details/105461971
- pytest-mian函数运行
1.设置多并发运行 1.命令行安装 pip install pytest-xdist #安装插件,进行多并发运行,#调用:-n -5 import pytest # pytest.main([&quo ...
- int,double与机器字长
机器字长:计算机能直接处理的二进制数据的位数,它决定了计算机的运算精度想深入了解. 学好汇编语言对你帮助非常大.汇编语言中的,最基本的数据类型有: (1) byte (2)word (3)double ...
- [gym102978D]Do Use FFT
前置知识 (以下内容并不严谨,可以参考论文<转置原理的简单介绍>) 对于一个算法,其为线性算法当且仅当仅包含以下操作: 1.$read\ i$,将$r_{i}$的值赋为(下一个)读入的元素 ...
- [hdu6995]Travel on Tree
问题即查询将其按照dfs序排序后,相邻两点(包括首尾)的距离和 考虑使用莫队+set维护,时间复杂度为$o(n\sqrt{n}\log n)$,无法通过 进一步的,注意到删除是可以用链表实现的,因此考 ...
- [bzoj1077]天平
先考虑如何求出任意两数的最大差值和最小差值,直接差分约束建图跑floyd求最短路和最长路即可然后枚举i和j,考虑dA+dB和di+dj的关系,分两种情况移项,转化成dA-di和dj-dB的关系或dA- ...