视频项目: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模型显示:
构造函数中:
//实例化model
m_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"); //QMYSQL
m_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]);
}
}
}
(存着自己看看)
项目原例子源码:链接
项目练习源码(跟博客相同,但是功能相比原例子不全):链接