QT7_视频知识点笔记_67_项目练习(页面以及对话框的切换,自定义数据类型,DB数据库类的自定义及使用)
视频项目:7----汽车销售管理系统(登录,品牌车管理,新车入库,销售统计图表)-----项目视频没有,代码也不全,更改项目练习:学生信息管理系统。
学生信息管理系统:简介:两个页面:主页面+学生信息添加页面(下面的例子仅举例学号和姓名)
1.点击添加按钮弹出添加对话框
添加一个继承自QDialog的QT界面类AddDialog(注意如果AddDialog是继承QWidget的话在主页面new 一个AddDialog的时候AddDialog页面会直接显示在主页面上)
主页面:
#include "adddialog.h"
...
AddDialog *m_addDialog; //添加学生信息窗口//构造函数:
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);m_addDialog = new AddDialog(this);
}
void Widget::on_pushButton_add_clicked()
{//点击按钮弹出新增窗口qDebug()<<"on_pushButton_add_clicked";m_addDialog->show();
}
2.添加按钮点击取消则关闭对话框
void AddDialog::on_btnCancel_clicked()
{qDebug()<<"on_btnCancel_clicked";this->close();
}
3.添加一个数据类定义需要存储数据类型(子界面存入,传递给主界面显示)
添加Q_DECLARE_METATYPE(type)宏,能使type类型让所有基于模板的函数识别
#ifndef CSTUDENTINFO_H
#define CSTUDENTINFO_H#include <QString>
#include <QMetaType>class CStudentInfo
{
public:CStudentInfo();bool setData(int id,QString name);int id() const;void setId(int id);QString name() const;void setName(const QString &name);private://此处举例仅用两个数据信息类int m_id; //学生id 四位数字QString m_name; //学生名称};Q_DECLARE_METATYPE(CStudentInfo)// 该宏放在类或结构体声明的最后面
#endif // CSTUDENTINFO_H
#include "cstudentinfo.h"CStudentInfo::CStudentInfo()
{}bool CStudentInfo::setData(int id, QString name)
{m_id = id;m_name = name;return true;
}int CStudentInfo::id() const
{return m_id;
}void CStudentInfo::setId(int id)
{m_id = id;
}QString CStudentInfo::name() const
{return m_name;
}void CStudentInfo::setName(const QString &name)
{m_name = name;
}
在子界面上按这个数据类存进入:
void AddDialog::on_btnConfirm_clicked()
{qDebug()<<"on_btnConfirm_clicked";//......//把检测合格的数据添加进入int id = ui->edtId->text().toInt();QString name = ui->edtName->text();//数据类型CStudentInfo stuInfo;stuInfo.setData(id,name);//仅进行数据的修改到主页面,对话框不关闭emit sig_addStuInfo(stuInfo);
}
通过信号槽把数据类接收,并显示在主页面:
信号槽传递:
//关联槽函数connect(m_addDialog,&AddDialog::sig_addStuInfo,this,&Widget::slot_addStuInfo);bool Widget::slot_addStuInfo(CStudentInfo &stuInfo)
{//收到添加对话框发出的信号,把添加的内容显示到UI上appendToModel(stuInfo); //此处可以收到信号传来的return true;
}
主页面model模型显示:
构造函数中:
//实例化modelm_standardModel = new QStandardItemModel(this);//设置tableView 菜单策略 customContextMenuRequested(const QPoint &pos)ui->tableView_StudentInfo->setContextMenuPolicy(Qt::CustomContextMenu);//添加表头QStringList headerList;headerList<<"学号"<<"姓名";m_standardModel->setHorizontalHeaderLabels(headerList);ui->tableView_StudentInfo->setModel(m_standardModel);
bool Widget::appendToModel(CStudentInfo &stuInfo)
{QStandardItem *itemId = new QStandardItem(QString("%1").arg(stuInfo.id(),4,10,QLatin1Char('0')));itemId->setCheckable(true); //添加复选框itemId->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);QStandardItem *itemName = new QStandardItem(stuInfo.name());itemName->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);QList<QStandardItem*> rowItem;rowItem.append(itemId);rowItem.append(itemName);m_standardModel->appendRow(rowItem);return true;}
效果:(后续需要添加学号是否存在验证等需另外再加入判断)
4.加入数据库进行数据的长期存储,主页面显示,子页面写入,以及删除功能
先创建一个数据库的类CDataSQLite:
#ifndef CDATASQLITE_H
#define CDATASQLITE_H#include "cstudentinfo.h"
#include <QSqlDatabase>class CDataSQLite
{
public:CDataSQLite();/*** @brief 查询所有信息* @param stuInfos* @return*///用来遍历virtual bool selectStuInfos(QList<CStudentInfo> &stuInfoList) ; //用来新增virtual bool addStuInfo(CStudentInfo &stuInfo) ; virtual bool updateStuInfo(CStudentInfo &stuInfo) ;//用来删除virtual bool deleteStuInfo(int id) ;
private:QSqlDatabase m_db; //数据库连接
};#endif // CDATASQLITE_H
CDataSQLite的构造函数:
//打开数据库m_db = QSqlDatabase::addDatabase("QSQLITE"); //QMYSQLm_db.setDatabaseName("./stuInfoDB_demo.db"); // 相对路径是相对于.exe所在的文件夹下(即bin文件夹下)if(!m_db.open()){qDebug() << "Failed to Open database";return;}qDebug() << "success Open ";//如果没有这个表则会创建QSqlQuery query;QString sql = QString("create table if not exists tb_stuInfo""(id int primary key not null,""name varchar(50),""overallScore real);");if(!query.exec(sql)){qDebug() << "Failed to create table";qDebug() << query.lastQuery();return;}//关闭数据库m_db.close();
bool CDataSQLite::addStuInfo(CStudentInfo &stuInfo)
{//新增if(!m_db.open()){qDebug() << "Failed to Open Database : addStuInfo";return false;}QSqlQuery query;query.prepare("insert into tb_stuInfo (id,name)""values(:id,:name)");query.bindValue(":id",stuInfo.id());query.bindValue(":name",stuInfo.name());if(!query.exec()){qDebug() << query.lastQuery();m_db.close();return false;}m_db.close();return true;}bool CDataSQLite::selectStuInfos(QList<CStudentInfo> &stuInfoList)
{//查询if(!m_db.open()){qDebug() << "Failed to Open Database : selectStuInfos";return false;}QSqlQuery query;QString sql = "Select * from tb_stuInfo;";if(!query.exec(sql)){qDebug() << "Failed to selcet tb_stuInfo;";return false;}while(query.next()){CStudentInfo stuInfo;int id = query.value("id").toInt();QString name = query.value("name").toString();stuInfo.setData(id,name);stuInfoList.append(stuInfo);}m_db.close();return true;
}bool CDataSQLite::deleteStuInfo(int id)
{if(!m_db.open()){qDebug() << "Failed to Open Database : deleteStuInfo";return false;}QSqlQuery query;QString sql = QString("delete from tb_stuInfo where id = %1").arg(id);if(!query.exec(sql)){qDebug() << "Failed to delete stuInfo!!!";m_db.close();return false;}m_db.close();return true;
}
使用CDataSQLite数据库类:
在主页面中,构造函数中会先实例化数据库类,然后进行遍历查询进行显示。
//在.h文件中
CDataSQLite *m_dataSource; //数据源//.cpp构造函数中
//实例化数据源m_dataSource = new CDataSQLite();//查询数据QList<CStudentInfo> stuInfoList;bool res = m_dataSource->selectStuInfos(stuInfoList);if(!res){QMessageBox::information(this,"提示","查询学生信息失败");return;}qDebug() << stuInfoList.size();for(int i=0;i<stuInfoList.size();++i){appendToModel(stuInfoList[i]);}
在新增页面点击确认发送信号之后,主页面接收到信号在槽函数中进行数据库类新增
//接收到子页面的确认添加按钮发出的处理信号的槽函数
bool Widget::slot_addStuInfo(CStudentInfo &stuInfo)
{//把数据添加到数据库中bool res = m_dataSource->addStuInfo(stuInfo);if(!res){QMessageBox::information(this,"提示","插入失败!!!");return false;}//收到添加对话框发出的信号,把添加的内容添加appendToModel(stuInfo);return true;
}
删除:主页面的删除按钮点击之后槽函数:on_pushButton_delate_clicked,会把勾选的数据从数据库中以及主页面中删除
void Widget::on_pushButton_delate_clicked()
{QMap<int,QStandardItem*> delRowsMap; //待删除的行for(int row = 0;row<m_standardModel->rowCount();++row){QStandardItem *item = m_standardModel->item(row);if(item->checkState() == Qt::Checked){delRowsMap.insert(row,item);}}if(delRowsMap.size()<1)return;//弹出删除提示int res = QMessageBox::information(this,"提示","是否真的要删除",QMessageBox::Yes|QMessageBox::No);if(res == QMessageBox::No) return;QList<int> keyList = delRowsMap.keys();//1.删除数据库中的数据for(int key=keyList.size()-1;key>=0;--key){if(m_dataSource->deleteStuInfo(delRowsMap.value(keyList[key])->text().toInt())){//2.删除窗口中的数据m_standardModel->removeRow(keyList[key]);}}}
(存着自己看看)
项目原例子源码:链接
项目练习源码(跟博客相同,但是功能相比原例子不全):链接
相关文章:

QT7_视频知识点笔记_67_项目练习(页面以及对话框的切换,自定义数据类型,DB数据库类的自定义及使用)
视频项目:7----汽车销售管理系统(登录,品牌车管理,新车入库,销售统计图表)-----项目视频没有,代码也不全,更改项目练习:学生信息管理系统。 学生信息管理系统࿱…...

windows10系统64位安装delphiXE11.2完整教程
windows10系统64位安装delphiXE11.2完整教程 https://altd.embarcadero.com/download/radstudio/11.0/radstudio_11_106491a.iso XE11.1 https://altd.embarcadero.com/download/radstudio/11.0/RADStudio_11_2_10937a.iso XE11.2 关键使用文件在以下内容:windows10…...

09.责任链模式
09. 责任链模式 什么是责任链设计模式? 责任链设计模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许将请求沿着处理者对象组成的链进行传递,直到有一个处理者对象能够处理该请求为止。这种模式的目的…...

Amazon云计算AWS(一)
目录 一、基础存储架构Dynamo(一)Dynamo概况(二)Dynamo架构的主要技术 二、弹性计算云EC2(一)EC2的基本架构(二)EC2的关键技术(三)EC2的安全及容错机制 提供的…...

十_信号4-SIGCHLD信号
SIGCHLD信号 在学习进程控制的时候,使用wait和waitpid系统调用何以回收僵尸进程,父进程可以阻塞等待,也可以非阻塞等待,采用轮询的方式不停查询子进程是否退出。 采用阻塞式等待,父进程就被阻塞了,什么都干…...

HCIP的学习(27)
RSTP—802.1W—快速生成树协议 STP缺陷: 1、收敛速度慢----STP的算法是一种被动的算法,依赖于计时器来进行状态变化 2、链路利用率低 RSTP向下兼容STP协议。(STP不兼容RSTP) 改进点1—端口角色 802.1D协议---根端口、指定端口…...

6. MySQL 查询、去重、别名
文章目录 【 1. 数据表查询 SELECT 】1.1 查询表中所有字段使用 * 查询表的所有字段列出表的所有字段 1.2 查询表中指定的字段 【 2. 去重 DISTINCT 】【 3. 设置别名 AS 】3.1 为表指定别名3.2 为字段指定别名 【 5. 限制查询结果的条数 LIMIT 】5.1 指定初始位置5.2 不指定初…...

Oracle导出clob字段到csv
使用UTL_FILE ref: How to Export The Table with a CLOB Column Into a CSV File using UTL_FILE ?(Doc ID 1967617.1) --preapre data CREATE TABLE TESTCLOB(ID NUMBER, MYCLOB1 CLOB, MYCLOB2 CLOB ); INSERT INTO TESTCLOB(ID,MYCLOB1,MYCLOB2) VALUES(1,Sample row 11…...
C++无锁(lock free)队列moodycamel::ConcurrentQueue
moodycamel::ConcurrentQueue介绍 moodycamel::ConcurrentQueue一个用C++11实现的多生产者、多消费者无锁队列。 它具有以下特点: 1.快的让人大吃一惊,详见不同无锁队列之间的压测对比 2.单头文件实现,很容易集成到你的项目中 3.完全线程安全的无锁队列,支持任意线程数的并…...

python办公自动化——(二)替换PPT文档中图形数据-柱图
效果: 数据替换前 : 替换数据后: 实现代码 import collections.abc from pptx import Presentation from pptx.util import Cm,Pt import pyodbc import pandas as pd from pptx.chart.data impo…...

vue不同页面切换的方式(Vue动态组件)
v-if实现 <!--Calender.vue--> <template><a-calendar v-model:value"value" panelChange"onPanelChange" /></template> <script setup> import { ref } from vue; const value ref(); const onPanelChange (value, mod…...

Linux下Qt Creator无法输入中文(已解决)
1. 首先确保安装了搜狗输入法,且能正常运行。 2.克隆源码到本地。 git clone https://gitcode.com/fcitx/fcitx-qt5.git 3.检查Qt Creator版本,如下图所示,为基于Qt6的。 4. 进入源码目录,建立build文件夹,修改CMak…...

Codeforces 提交Java代码(自己处理输入输出)
示例一(A. Watermelon) 题目地址 Problem - 4A - Codeforces 题目截图 提交方式 可以提交本地文件,也可以在线提交。我们这里选择在线提交方式,点击上图中的 SUBMIT 按钮,会进入如下界面。 输入Java代码效果如下&a…...
剖析vue中nextTick源码
代码逻辑梳理: callbacks 数组用于存储待执行的回调函数,waiting 变量用于标记是否有待执行的回调函数。 flushCallbacks 函数用于执行所有存储在 callbacks 数组中的回调函数,并在执行完成后将 waiting 设置为 false。 timer 函数根据环境…...

SSM牙科诊所管理系统-计算机毕业设计源码98077
目 录 摘要 1 绪论 1.1研究目的与意义 1.2国内外研究现状 1.3ssm框架介绍 1.4论文结构与章节安排 2 牙科诊所管理系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能…...

【C++进阶】深入STL之string:模拟实现走进C++字符串的世界
📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C “ 登神长阶 ” 🤡往期回顾🤡:C模板入门 🌹🌹期待您的关注 🌹🌹 ❀STL之string 📒1. string…...

go语言linux安装
下载:https://go.dev/dl/ 命令行使用 wget https://dl.google.com/go/go1.19.3.linux-amd64.tar.gz解压下载的压缩包,linux建议放在/opt目录下 我放在/home/ihan/go_sdk下 sudo tar -C /home/ihan/go_sdk -xzf go1.19.3.linux-amd64.tar.gz 这里的参数…...
vi和vim有什么不同?
vi 和 vim 都是流行的文本编辑器,它们之间有以下主要区别: 历史: vi 是一个非常古老的文本编辑器,最初由 Bill Joy 在 1976 年为 Unix 系统编写。vim(Vi IMproved)是 vi 的一个增强版,由 Bram M…...
CSS动画效果(鼠标滑过按钮动画)
1.整体效果 https://mmbiz.qpic.cn/sz_mmbiz_gif/EGZdlrTDJa5SXiaicFfsrcric7TJmGO6YddqC4wFPdM7PGzPHuFgvtDS7MIvnLHB4WFaKia0Qh8VCyUaoyHMc2Zltg/640?wx_fmtgif&fromappmsg&tpwebp&wxfrom5&wx_lazy1&wx_co1 网页设计中的按钮不仅是用户交互的桥梁&#…...

数据结构(C):从初识堆到堆排序的实现
目录 🌞0.前言 🚈 1.堆的概念 🚈 2.堆的实现 🚝2.1堆向下调整算法 🚝2.2堆的创建(堆向下调整算法) ✈️2.2.1 向下调整建堆时间复杂度 🚝2.3堆向上调整算法 🚝2.…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...