当前位置: 首页 > news >正文

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数据库类的自定义及使用)

视频项目&#xff1a;7----汽车销售管理系统&#xff08;登录&#xff0c;品牌车管理&#xff0c;新车入库&#xff0c;销售统计图表&#xff09;-----项目视频没有&#xff0c;代码也不全&#xff0c;更改项目练习&#xff1a;学生信息管理系统。 学生信息管理系统&#xff1…...

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 关键使用文件在以下内容&#xff1a;windows10…...

09.责任链模式

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

Amazon云计算AWS(一)

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

十_信号4-SIGCHLD信号

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

HCIP的学习(27)

RSTP—802.1W—快速生成树协议 STP缺陷&#xff1a; 1、收敛速度慢----STP的算法是一种被动的算法&#xff0c;依赖于计时器来进行状态变化 2、链路利用率低​ RSTP向下兼容STP协议。&#xff08;STP不兼容RSTP&#xff09; 改进点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文档中图形数据-柱图

效果: 数据替换前 &#xff1a; 替换数据后&#xff1a; 实现代码 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. 首先确保安装了搜狗输入法&#xff0c;且能正常运行。 2.克隆源码到本地。 git clone https://gitcode.com/fcitx/fcitx-qt5.git 3.检查Qt Creator版本&#xff0c;如下图所示&#xff0c;为基于Qt6的。 4. 进入源码目录&#xff0c;建立build文件夹&#xff0c;修改CMak…...

Codeforces 提交Java代码(自己处理输入输出)

示例一&#xff08;A. Watermelon&#xff09; 题目地址 Problem - 4A - Codeforces 题目截图 提交方式 可以提交本地文件&#xff0c;也可以在线提交。我们这里选择在线提交方式&#xff0c;点击上图中的 SUBMIT 按钮&#xff0c;会进入如下界面。 输入Java代码效果如下&a…...

剖析vue中nextTick源码

代码逻辑梳理&#xff1a; callbacks 数组用于存储待执行的回调函数&#xff0c;waiting 变量用于标记是否有待执行的回调函数。 flushCallbacks 函数用于执行所有存储在 callbacks 数组中的回调函数&#xff0c;并在执行完成后将 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++字符串的世界

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;C模板入门 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀STL之string &#x1f4d2;1. string…...

go语言linux安装

下载&#xff1a;https://go.dev/dl/ 命令行使用 wget https://dl.google.com/go/go1.19.3.linux-amd64.tar.gz解压下载的压缩包&#xff0c;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 都是流行的文本编辑器&#xff0c;它们之间有以下主要区别&#xff1a; 历史&#xff1a; vi 是一个非常古老的文本编辑器&#xff0c;最初由 Bill Joy 在 1976 年为 Unix 系统编写。vim&#xff08;Vi IMproved&#xff09;是 vi 的一个增强版&#xff0c;由 Bram M…...

CSS动画效果(鼠标滑过按钮动画)

1.整体效果 https://mmbiz.qpic.cn/sz_mmbiz_gif/EGZdlrTDJa5SXiaicFfsrcric7TJmGO6YddqC4wFPdM7PGzPHuFgvtDS7MIvnLHB4WFaKia0Qh8VCyUaoyHMc2Zltg/640?wx_fmtgif&fromappmsg&tpwebp&wxfrom5&wx_lazy1&wx_co1 网页设计中的按钮不仅是用户交互的桥梁&#…...

数据结构(C):从初识堆到堆排序的实现

目录 &#x1f31e;0.前言 &#x1f688; 1.堆的概念 &#x1f688; 2.堆的实现 &#x1f69d;2.1堆向下调整算法 &#x1f69d;2.2堆的创建&#xff08;堆向下调整算法&#xff09; ✈️2.2.1 向下调整建堆时间复杂度 &#x1f69d;2.3堆向上调整算法 &#x1f69d;2.…...

使用mcp-maker快速构建AI工具集成服务器:从MCP协议到实践

1. 项目概述&#xff1a;一个为AI应用注入“超能力”的MCP服务器工厂 如果你最近在折腾AI应用开发&#xff0c;特别是想给ChatGPT、Claude这类大模型配上“手和脚”&#xff0c;让它们能操作你的本地文件、查询数据库&#xff0c;甚至控制你的智能家居&#xff0c;那你大概率已…...

告别标题栏!在RK3568 Buildroot固件上,让你的Qt应用开机全屏显示的保姆级教程

RK3568嵌入式全屏实战&#xff1a;从Weston配置到Qt应用独占显示的完整指南 在嵌入式Linux系统开发中&#xff0c;GUI应用的全屏显示往往成为工程师面临的第一个"拦路虎"。当你在RK3568平台上精心开发的Qt应用启动后&#xff0c;却发现屏幕顶部顽固地挂着Weston窗口管…...

怎么判断一家工厂还在不在正常生产?6 类活跃度信号,从纸面到现场

跑工厂的销售员都遇到过这种事&#xff1a;手机里存着一份名单&#xff0c;导航开两小时&#xff0c;到门口才发现卷帘门焊死、车间长草、保安说"厂子去年就搬了"。 问题出在哪&#xff1f;大多数人判断"这家工厂在不在"&#xff0c;靠的是工商登记——执照…...

脉冲神经网络与神经形态计算的能效优化实践

1. 脉冲神经网络与神经形态计算基础脉冲神经网络&#xff08;SNN&#xff09;作为第三代神经网络模型&#xff0c;其核心在于模拟生物神经系统的信息处理机制。与传统人工神经网络&#xff08;ANN&#xff09;相比&#xff0c;SNN具有三个本质区别&#xff1a;首先&#xff0c;…...

【Canvas动画录制实战】从WebM到MP4:MediaRecorder全流程解析与避坑指南

1. Canvas动画录制基础与准备工作 如果你正在开发一个数据可视化项目或者HTML5小游戏&#xff0c;可能会遇到需要将动态内容保存为视频的需求。Canvas动画录制就是解决这个问题的关键技术方案。相比传统的录屏软件&#xff0c;直接通过代码录制能获得更清晰的画质&#xff0c;还…...

基于BLE信号强度的寻物游戏:用CircuitPython实现无线接近探测

1. 项目概述&#xff1a;一个用蓝牙信号“捉迷藏”的硬件游戏几年前我第一次接触Adafruit的Circuit Playground系列开发板时&#xff0c;就被它那种“开箱即玩”的理念吸引了。它把LED、按钮、传感器都集成在一块板子上&#xff0c;让你不用焊接就能快速验证想法。后来出的Circ…...

RFM69无线通信进阶:从基础收发到可靠数据传输系统构建

1. 项目概述&#xff1a;从点对点收发迈向可靠通信在物联网和嵌入式开发领域&#xff0c;无线通信模块是连接物理世界与数字世界的桥梁。RFM69系列模块&#xff0c;特别是工作在433MHz或915MHz等Sub-GHz频段的RFM69HCW&#xff0c;因其出色的抗干扰能力、较远的传输距离以及相对…...

小米汽车Q3真车现身:科技巨头跨界造车的技术路径与市场挑战

1. 项目概述&#xff1a;从“Q3真车现身”看小米汽车的阶段性成果最近&#xff0c;小米汽车项目代号“Q3”的测试车辆在公开道路上被频繁捕获&#xff0c;这已经不是简单的谍照&#xff0c;而是接近量产状态的“真车”现身。作为一名长期关注汽车产业变革&#xff0c;特别是科技…...

CircuitPython实战:I2S音频播放与asyncio异步编程构建智能温度监测系统

1. 项目概述与核心价值如果你正在寻找一种能让你的嵌入式项目“开口说话”或者“耳听八方”的方案&#xff0c;I2S音频绝对是你绕不开的技术。不同于我们熟悉的模拟音频&#xff0c;I2S是一种纯粹的数字音频传输协议&#xff0c;它通过三根线——时钟、声道选择和数据——就能传…...

AI应用开发实战:从RAG系统到多模型API调用的开源项目解析

1. 项目概述&#xff1a;一个AI项目的开源实践最近在GitHub上看到一个名为“hferello/ai”的项目&#xff0c;这个标题非常简洁&#xff0c;甚至可以说有些“神秘”。乍一看&#xff0c;它可能是一个关于人工智能的通用仓库&#xff0c;但点进去之后&#xff0c;你会发现它远不…...