目录
Qt学生管理系统1项目设计与布局开发_哔哩哔哩_bilibili
第一章 UI界面设计与开发
登录界面
第一步先做登录界面
新建一个文件,命名为Page_login.
在MainWindows.h头文件里声明一个Page_login类型的变量m_dlgloin:
先放置控件:
设置控件属性
然后我们将用户名输入和密码输入框设置成为默认显示:
将密码输入框的模式改为密码模式:
将用户名和密码输入长度限制为8位:
在MainWindows.cpp文件里调用我们我们m_dlogin窗口,并且把主窗口阻塞不显示:
初步登录界面如下:
右击按钮选择转到槽:会自动生成框架:
我们接下来登录和退出的逻辑
退出
exit(0);
登录
登录一般是在数据库查找用户名和密码,查找到了就发送一个signal显示成功了:
如果失败就提示登录失败.
在Mainwindows.cpp里写下面这段代码,表示如果主界面捕获到来自登录界面登录成功的信号,那么就跳到主界面:
主界面
主界面放置如下控件:效果图如下:
改变一下背景色
往treewidget里添加信息
需要用到的函数:
所以我们需要new一个 QTreeWidgetItem 类型对象. QTreeWidgetItem 的构造函数如下:第一个参数要为自身,第二个参数想用字符串的话只能构造一个qstringlist类型的参数
效果图:
让文字居左显示(把indentation设为小一点):
构造两个子集目录:学生管理,管理员管理
效果图如下:
数据模拟
把我们之前的stackwidget设置一个背景色,然后在stackwidget里加一个tablewidget控件,给tablewidget加几列数据,效果图如下:
UI美化
在Mainwindows.cpp里面的Widget类里面有一个keyPressEvent()键盘响应事件函数,它的声明如下:
virtual void keyPressEvent(QKeyEvent *event);
我们在Mainwindows.h文件里进行声明,然后在Mainwindows.cpp文件进行定义.定义如下:
我们通过f6键进行换肤,首先提前新建一个stucss.css文件,在里面我们要换的样式写好,然后在我们按完F6之后将其加载进我们的UI界面
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if(event->key()==Qt::Key_F6)
{
QFile f;
auto str=QCoreApplication::applicationDirPath(); //获取application的路径
f.setFileName(str+"//"+"stucss.css"); //将路径后加上我们皮肤的路径
f.open(QIODevice::ReadOnly); //以只读方式打开
QString str2=f.readAll(); //读取
this->setStyleSheet(str2); //设置样式
m_dlgloion.setStyleSheet(str2);//采用样式
}
}
stucss.css代码如下:
/* 登录界面 */
QPushButton{color:white;background-color:#34495e;border-radius:6;} /*按钮*/
QLabel{color:#34495e;} /*标签*/
QLabel#lb1{color:#34495e;font-size: 22;} /*用户名标签*/
QLabel#lb2{color:#34495e;font-size: 22;} /*密码标签*/
QLineEdit{border: 2px solid #bdc3c7; min-height:22; border-radius: 6px;}/*搜索框 */
/* 主界面 */
/* Widget#background-color:#34495e; */
QLabel[lab="main"]{color:white;}
QWidget#widget[bg_title="main"]{background-color:#34495e;}
QWidget#widget_3{background-color:#34495e;}
QPushButton[btn="main"]{font-family:"微软雅黑";min-height:22px;min-width:80px;background-color: #16a085;border-radius:6; } /*主界面按钮*/
QPushButton[btn="main"]:pressed{font-family:"微软雅黑";min-height:22px;min-width:80px;background-color: #2a5d53;border-radius:6; } /*按钮按压变色*/
/*左侧界面样式*/
QTreeWidget{font-family:"宋体";font-size:15px;background-color: rgba(52, 73, 94, 150); color:white;}
QStackedWidget{border:1px solid gray;} 边框
/*右侧界面样式*/
QHeaderView::section
{
font-size:16px;
font-family: "宋体";
text-align:center;
height:30px;
color:#909399;
font-weight: bold;
border:1px solid gray;
border-left:none;
/* border-bottom-color: rgb(168, 171, 180); */
}
QTableWidget::item
{
font:14px "微软雅黑";
color:#667483;
border:none;
}
优化完之后的效果如下所示:
第二章 数据库设计与开发
数据库设计
新建两张表,sql语句如下:
学生表
CREATE TABLE "student" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" TEXT,
"age" integer,
"grade" integer,
"class" integer,
"studentid " integer,
"phone" TEXT,
"wechat" TEXT
);
用户表
CREATE TABLE "username" (
"username" TEXT,
"password" TEXT,
"auth" TEXT
);
此时数据库里就有两张表了
创建一个新的基于OBject类的头文件,命名为stusql.cpp
在这个文件进行数据库操作
连接数据库
连接数据库的模板如下:
#include "stusql.h"
#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
stusql::stusql(QObject *parent )
: QObject {parent}
{
// 检查是否有可用的数据库驱动
if (QSqlDatabase::drivers().isEmpty()) {
// 确保 stusql 类是 QObject 的子类,否则需要传递一个有效的 QWidget 指针或 nullptr
QMessageBox::information(nullptr, tr("No database drivers found"),
tr("This demo requires at least one Qt database driver. "
"Please check the documentation how to build the "
"Qt SQL plugins."));
return;
}
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); // 创建一个数据库连接
db.setDatabaseName("./data.db");
if (!db.open()) {
qDebug() << "数据库文件加载失败: " << db.lastError().text();
// 这里可能需要处理错误,比如显示一个消息框或者记录日志
return; // 数据库打开失败,构造函数不应该继续执行
}
qDebug() << "打开数据库文件成功";
此时构建完之后控制台显示
然后我们可以向数据库里插一条数据看一下是否可以插入成功:
语句如下:
QSqlQuery q("", db);
if (!q.exec("INSERT INTO student VALUES (NULL ,'张三',12,3,2,1,15518978071,'aasDASD')")) {
qDebug() << "插入数据失败: " << q.lastError().text();
// 这里应该处理SQL执行错误
}
此时构建完之后控制台显示:
我们现在可以让插入失败的原因可视化的显示出来:
if (!q.exec("INSERT INTO student VALUES (NULL ,'张三',12,3,2,1,15518978071,'aasDASD')")) {
QMessageBox::critical(nullptr, tr("Database Error"),
tr("Failed to insert data: %1").arg(q.lastError().text()));
// 显示具体的错误信息
}
这样的话就会有一个断言:显示表不存在
我把路径换成绝对路径就可以了:
db.setDatabaseName("D:\\QTproject\\stumanger\\data.db");
现在数据库里student表就被插入一条数据了:
数据库功能设计
sql语句设计
查询所有学生数量
select count(id) from student;
查询第几页学生数据
offset代表从第几条记录之后"开始"查询,limit表示查询多少条结果
select * from student order by id limit 2 offset 1;
删除学生
delete from student where id = 1;
修改学生信息
update student set name = 'asd' where id=25;
清空学生表
delete from student
添加单个用户
INSERT INTO "username" VALUES ('admin', 111, 'admin');
删除单个用户
delete from username where username='admin';
修改用户权限
update username set auth='user';
查询所有用户
select * from username
查询用户是否存在
select *from username where username='admin';
数据库函数设计
实现基础的数据库增删查改功能,在stusql.h文件里列出以下声明:
首先创建两个结构体
在stusql.cpp文件里实现定义:
sql函数设计
学生表操作
Init()
在初始化的时候进行数据库连接
void stusql::Init()
{
m_db = QSqlDatabase::addDatabase("QSQLITE"); // 创建一个数据库连接
m_db.setDatabaseName("D:\\QTproject\\stumanger\\data.db");
#if 0
auto str=QCoreApplication::applicationDirPath(); //获取一下数据库的路径,目的是为了发布时找到数据库将其放于当前目录下
qDebug()<<str;
#endif
if (!m_db.open()) {
QMessageBox::critical(nullptr, tr("Database Error"),
tr("Failed to open database: %1").arg(m_db.lastError().text()));
return; // 数据库打开失败,构造函数不应该继续执行
}
qDebug() << "打开数据库文件成功";
}
getStuCnt()
quint32 stusql::getStuCnt()
{
QSqlQuery sql(m_db);
sql.exec("select count(id) from student;");
quint32 Cnt=0;
while(sql.next())
{
Cnt=sql.value(0).toUInt();
}
qDebug() << "学生数量: " << Cnt;
return Cnt;
}
getPageStu()
QList<StuInfo> stusql::getPageStu(quint32 page, quint32 Cnt)
{
QList<StuInfo> l;
QSqlQuery sql(m_db);
QString strsql=QString("select * from student order by id limit %1 offset %2;")
.arg(Cnt)
.arg(page*Cnt);
sql.exec(strsql);
StuInfo info;
while(sql.next())
{
info.id=sql.value(0).toUInt();
info.stu_name=sql.value(1).toString();
info.stu_age=sql.value(2).toUInt();
info.stu_grade=sql.value(3).toUInt();
info.stu_class=sql.value(4).toUInt();
info.stu_id=sql.value(5).toUInt();
info.stu_phone=sql.value(6).toString();
info.stu_wechat=sql.value(7).toString();
}
l.push_back(info);
// qDebug()<<l.begin()->id<<l.begin()->stu_name<<l.begin()->stu_age;
return l;
}
addStu()
添加记录
bool stusql::addstu(StuInfo info)
{
QSqlQuery sql(m_db);
QString strsql=QString("insert into student values(null,'%1',%2,%3,%4,%5,'%6','%7')")
.arg(info.stu_name)
.arg(info.stu_age)
.arg(info.stu_grade)
.arg(info.stu_class)
.arg(info.stu_id)
.arg(info.stu_phone)
.arg(info.stu_wechat);
if(!sql.exec(strsql))
{
QMessageBox::critical(nullptr, tr("Database Error"),
tr("Failed to insert data: %1").arg(sql.lastError().text()));
// 显示具体的错误信息
return false;
}
return true;
}
delStu()
bool stusql::delStu(int id)
{
QSqlQuery sql(m_db);
QString strsql=QString("delete from student where id= %1;")
.arg(id);
if(sql.exec(strsql))
{
return true;
}
else qDebug()<<"删除失败!";
return false;
}
updateInfo()
修改学生信息
bool stusql::updateInfo(StuInfo info)
{
QSqlQuery sql(m_db);
QString strsql=QString("update student set name = '%1' where id=%2;")
.arg(info.stu_name)
.arg(info.stu_id);
bool res=sql.exec(strsql);
QSqlError e=sql.lastError();
if(sql.isValid())
{
qDebug()<<e.text();
}
return res;
}
发现怎么修改都无法修改,后来发现是建表的问题(字段名后面有空格)
clearStuInfo()
清空学生表
void stusql::clearStuInfo()
{
QSqlQuery sql(m_db);
QString strsql=QString("delete from student");
sql.exec(strsql);
}
在表设计视图里面把这些空格删掉就可以了
用户表操作
addUser()
//添加单个用户
bool stusql::addUser(UserInfo info)
{
QSqlQuery sql(m_db);
QString strsql = QString("INSERT INTO username VALUES ('%1', '%2', '%3');")
.arg(info.username)
.arg(info.passwd)
.arg(info.auth);
if(!sql.exec(strsql))
{
qDebug()<<"ERROR:"<<sql.lastError();
return false;
}
return true;
}
delUser()
bool stusql::delUser(QString userName)
{
QSqlQuery sql(m_db);
QString strsql =QString("delete from username where username= '%1'").arg(userName);
if(!sql.exec(strsql))
{
qDebug()<<"ERROR:"<<sql.lastError();
return false;
}
return true;
}
UpdateUserAut()
bool stusql::UpdateUserAut(QString str1, QString str2)
{
QSqlQuery sql(m_db);
// 使用参数化查询来避免SQL注入
QString strsql = "UPDATE username SET auth = :auth WHERE username = :username;";
// 绑定参数
sql.prepare(strsql);
sql.bindValue(":auth", str1);
sql.bindValue(":username", str2);
if (!sql.exec()) {
qDebug() << "ERROR:" << sql.lastError();
return false;
}
// 检查是否有行被更新
if (sql.numRowsAffected() > 0) {
return true;
} else {
// 没有行被更新,可能是没有找到匹配的用户名
qDebug() << "No rows updated. User may not exist.";
return false;
}
}
getAllUser()
QList<UserInfo> stusql::getAllUser()
{
QList<UserInfo> l; // 使用正确的类型
QSqlQuery sql(m_db);
QString strsql = "select * from username"; // 假设表名正确
// 执行SQL查询
if (!sql.exec(strsql)) {
// 处理错误,例如打印错误信息
qDebug() << "Error executing query:" << sql.lastError();
return l; // 返回空列表或根据需要进行错误处理
}
UserInfo info; // 在循环内部初始化
while (sql.next()) {
info.username = sql.value("username").toString(); // 假设列名为 "username"
info.passwd = sql.value("passwd").toString(); // 假设列名为 "passwd"
info.auth = sql.value("auth").toString(); // 假设列名为 "auth"
l.push_back(info); // 在每次迭代中将info添加到列表
info = UserInfo(); // 重置info对象(如果UserInfo有默认构造函数)
}
auto a=l.front();
qDebug()<<a.username<<a.passwd<<a.auth;
return l;
}
isExists()
bool stusql::isExists(QString Name)
{
QSqlQuery sql(m_db);
// 使用参数化查询来避免SQL注入,并且只查询需要的列
QString strsql = "SELECT COUNT(*) FROM username WHERE username = :name;";
// 绑定参数
sql.prepare(strsql);
sql.bindValue(":name", Name);
if (!sql.exec()) {
qDebug() << "ERROR:" << sql.lastError();
return false;
}
// 检查是否有结果返回
if (sql.next()) {
// 检查COUNT(*)是否大于0
if(sql.value(0).toLongLong() > 0)
qDebug()<<"用户存在";
else qDebug()<<"用户不存在";
}
return false;
}
造一行数据,我们发现左边会有一个自增id:我们可以通过取消一个属性将其去掉:
模拟数据
创建单例
创建单例的目的:
单例模式是qt开发的一种模式.在发布的时候有两种模式,一种是怎么把资源载入exe文件当中,还有一种就是在发布的时候引入外部资源,这种模式占用内容特别少,就是单例模式.
我们在stusql.h文件里添加单利模式的声明
static stusql *ptrstuSql;
static stusql *getinstance()
{
if(ptrstuSql==nullptr)
{
ptrstuSql=new stusql;
}
return ptrstuSql;
}
在stusql.cpp文件里面添加对单例的定义:
stusql *stusql::ptrstuSql=nullptr;
我们创建一个QStringList类型对象mlNames,然后将1000个名字读入到mlNames里面.
然后我们在主界面添加一个按钮命名为btn_moni,然后添加定义,定义如下:
void MainWindow::on_btn_moni_clicked()
{
QString l;
//制作1000条学生数据
QRandomGenerator g,c;
g.seed(0);
c.seed(0);
for(int i=0;i<mlNames.size();i++)
{
auto rand_grade=g.bounded(7,10);
auto rand_class=g.bounded(1,10);
StuInfo info;
info.stu_name=mlNames[i];
if(i%3)
{
info.stu_age=14;
}
if(i%7)
{
info.stu_age=13;
}
if(i%9)
{
info.stu_age=18;
}
info.stu_grade=rand_grade;
info.stu_class=rand_class;
info.id=i;
info.stu_phone="13463464347";
info.stu_wechat="sfwegewg";
m_ptrStusql->addstu(info);
}
}
此时我们的数据库里就有了我们模拟的数据了:
接下来我们需要将这些数据展现在我们的Qtablewidget上.
我们写一个Update()函数,内容如下:
//刷新数据
void MainWindow::updateTable()
{
//把自带的表头删了,我们自己来写表头
ui->tableWidget_2->clear();
//必须要告诉编译器有多少列才能显示表头
ui->tableWidget_2->setColumnCount(8);
QStringList l;
//自定义表头
l<<"序号"<<"姓名"<<"年龄"<<"年纪"<<"班级"<<"学号"<<"电话"<<"微信";
ui->tableWidget_2->setHorizontalHeaderLabels(l); //设置显示表头
ui->tableWidget_2->setSelectionBehavior(QAbstractItemView::SelectRows); //当用户点击任何一个单元格时,整个行都会被选中
//显示数据内容
auto cnt=m_ptrStusql->getStuCnt(); //获取记录行数
ui->lb_cnt->setText(QString("数量:%1").arg(cnt)); //显示学生数量
QList<StuInfo> lStudents=m_ptrStusql->getPageStu(0,cnt); //获取一共有多少页数据
ui->tableWidget_2->setRowCount(cnt); //设置行数
//将数据刷新到tablewidget上
for(int i=0;i<lStudents.size();i++)
{
ui->tableWidget_2->setItem(i,0,new QTableWidgetItem(QString::number(i)));
ui->tableWidget_2->setItem(i,1,new QTableWidgetItem(lStudents[i].stu_name));
ui->tableWidget_2->setItem(i,2,new QTableWidgetItem(QString::number(lStudents[i].stu_age)));
ui->tableWidget_2->setItem(i,3,new QTableWidgetItem(QString::number(lStudents[i].stu_grade)));
ui->tableWidget_2->setItem(i,4,new QTableWidgetItem(QString::number(lStudents[i].stu_class)));
ui->tableWidget_2->setItem(i,5,new QTableWidgetItem(QString::number(lStudents[i].stu_id)));
ui->tableWidget_2->setItem(i,6,new QTableWidgetItem(lStudents[i].stu_phone));
ui->tableWidget_2->setItem(i,7,new QTableWidgetItem(lStudents[i].stu_wechat));
}
}
此时我们的数据就刷新出来了:
增
接下来我们实现这几个按钮的功能:
先来实现增加按钮的功能.创建一个dlg_addstu文件,dlg_addstu.ui如下:
然后我们还有个修改操作,就不单独设计UI界面,直接用dlg_addstu.ui的界面.
我们用一个全局变量m_isAdd,如果m_isAdd为True表示当前是添加操作,为false表示当前是修改操作.
dlg_addstu.ui界面的保存按钮和取消按钮定义如下:
增加操作是我们获取一下每个输入框输入的内容,把这些信息全部传给变量info,然后再把Info作为参数传给addStu()函数执行insert SQL语句.
//保存
void Dlg_AddStu::on_btn_save_clicked()
{
StuInfo info; //把所有的字段读取到info里
auto ptr=stusql::getinstance();
info.id=m_info.id; //传id
info.stu_name=ui->le_name->text();
info.stu_age=ui->sb_age->text().toInt();
info.stu_grade=ui->le_grade->text().toInt();
info.stu_class=ui->le_class->text().toInt();
info.stu_id=ui->le_id->text().toUInt();
info.stu_phone=ui->le_phone->text();
info.stu_wechat=ui->le_wechat->text();
if(m_isAdd) //为true表示当前是添加操作
{
ptr->addstu(info);
}
else
{ //为false表示当前是修改操作
ptr->updateInfo(info);
}
QMessageBox::information(nullptr,"消息","添加成功");
this->hide(); //点击保存之后窗口消失
}
void Dlg_AddStu::setType(bool isAdd,StuInfo info)
{
m_isAdd=isAdd;
m_info=info; //把info的所有信息都给中间变量m_info,包括id
ui->le_name->setText(info.stu_name);
ui->sb_age->setValue(info.stu_age);
ui->le_grade->setText(QString::number(info.stu_grade));
ui->le_class->setText(QString::number(info.stu_class));
ui->le_phone->setText(QString(info.stu_phone));
ui->le_wechat->setText(QString(info.stu_wechat));
}
取消按钮
//取消
void Dlg_AddStu::on_btn_cancel_clicked()
{
this->hide();
}
添加按钮(调出添加输入框)
//点击添加按钮弹出添加界面
void MainWindow::on_btn_add_clicked()
{
m_dlgAddstu.setType(true); //表示true代表当前是添加操作,false代表当前是修改操作
m_dlgAddstu.exec(); //模态对话框 当前界面不操作完不能操作其他界面
// m_dlgAddstu.show(); //非模态对话框
updateTable(); //添加完成之后刷新一下界面
}
删
//删除按钮的定义如下
void MainWindow::on_btn_del_clicked()
{
int i=ui->tableWidget_2->currentRow(); //获取一下鼠标点击的记录(即需要删除的记录)
if(i>=0) //如果要删除的记录是合法记录 (即不是不存在的记录),那么就进行删除
{
int id=ui->tableWidget_2->item(i,1)->text().toUInt(); //删除需要通过id删除,这里获取id
m_ptrStusql->delStu(id); //传给我们定义的delStu()函数执行删除sql语句
updateTable(); //删除完之后刷新一下界面
QMessageBox::information(nullptr,"信息","删除成功");
}
}
查询
//搜索
void MainWindow::on_btn_seacher_clicked()
{
QString SearchFile=ui->lb_search->text(); //获取搜索输入框输入的内容
//如果输入框的内容为空就退出查询
if(SearchFile.isEmpty())
{
QMessageBox::information(nullptr,"信息","查询为空!");
updateTable();
return;
}
//必须要告诉编译器有多少列才能显示表头
ui->tableWidget_2->clear();
ui->tableWidget_2->setColumnCount(9);
QStringList l;
//自定义表头
l<<"序号"<<"id"<<"姓名"<<"年龄"<<"年纪"<<"班级"<<"学号"<<"电话"<<"微信";
ui->tableWidget_2->setHorizontalHeaderLabels(l); //设置显示表头
ui->tableWidget_2->setSelectionBehavior(QAbstractItemView::SelectRows); //当用户点击任何一个单元格时,整个行都会被选中
//显示数据内容
auto cnt=m_ptrStusql->getStuCnt(); //获取记录行数
ui->lb_cnt->setText(QString("数量:%1").arg(cnt)); //显示学生数量
ui->tableWidget_2->setSelectionBehavior(QAbstractItemView::SelectRows);//单击选中一行
ui->tableWidget_2->setEditTriggers(QAbstractItemView::NoEditTriggers);//使记录不可被直接编辑
QList<StuInfo> lStudents=m_ptrStusql->getPageStu(0,cnt); //获取一共有多少页数据
int index=0;
//将数据刷新到tablewidget上
for(int i=0;i<lStudents.size();i++)
{
//如果查询不到这个人就不执行下面的操作
if(!lStudents[i].stu_name.contains(SearchFile))
{
continue;
}
index++;
ui->tableWidget_2->setItem(i,0,new QTableWidgetItem(QString::number(index)));
ui->tableWidget_2->setItem(i,1,new QTableWidgetItem(QString::number(lStudents[i].id)));
ui->tableWidget_2->setItem(i,2,new QTableWidgetItem(lStudents[i].stu_name));
ui->tableWidget_2->setItem(i,3,new QTableWidgetItem(QString::number(lStudents[i].stu_age)));
ui->tableWidget_2->setItem(i,4,new QTableWidgetItem(QString::number(lStudents[i].stu_grade)));
ui->tableWidget_2->setItem(i,5,new QTableWidgetItem(QString::number(lStudents[i].stu_class)));
ui->tableWidget_2->setItem(i,6,new QTableWidgetItem(QString::number(lStudents[i].stu_id)));
ui->tableWidget_2->setItem(i,7,new QTableWidgetItem(lStudents[i].stu_phone));
ui->tableWidget_2->setItem(i,8,new QTableWidgetItem(lStudents[i].stu_wechat));
}
//最后统计一下查询出来的人数
ui->tableWidget_2->setRowCount(index); //设置行数
}
修改
//修改按钮
void MainWindow::on_btn_modify_clicked()
{
StuInfo info; //把当前鼠标点击的记录的每个字段添加到info里
int i=ui->tableWidget_2->currentRow(); //获取鼠标点击的行(即要修改的记录)
if(i>=0)
{
info.id=ui->tableWidget_2->item(i,1)->text().toUInt(); //获取id的值并保存在Info里
info.stu_name=ui->tableWidget_2->item(i,2)->text();
info.stu_age=ui->tableWidget_2->item(i,3)->text().toUInt();
info.stu_grade=ui->tableWidget_2->item(i,4)->text().toUInt();
info.stu_class=ui->tableWidget_2->item(i,5)->text().toUInt();
info.stu_id=ui->tableWidget_2->item(i,6)->text().toUInt();
info.stu_phone=ui->tableWidget_2->item(i,7)->text();
info.stu_wechat=ui->tableWidget_2->item(i,8)->text();
m_dlgAddstu.setType(false,info);
m_dlgAddstu.exec();
}
updateTable(); //更新完之后把界面刷新一下
}
清空学生表
//清除学生表
void MainWindow::on_btn_StuClear_clicked()
{
m_ptrStusql->clearStuInfo();
updateTable();
}
优化
优化一下数据模拟的加载时间
也就是优化一下add()函数
我们用QList<StuInfo> l来接收所有的添加信息,再通过循环从l里读取每条记录进行,执行添加sql语句,再把事务打开.
//添加学生
bool stusql::addstu(QList<StuInfo> l)
{
QSqlQuery sql(m_db);
m_db.transaction(); //开启事务
for(auto info:l)
{
QString strsql = QString("INSERT INTO student VALUES (NULL, '%1', %2, %3, %4, %5, '%6', '%7')")
.arg(info.stu_name)
.arg(info.stu_age)
.arg(info.stu_grade)
.arg(info.stu_class)
.arg(info.stu_id)
.arg(info.stu_phone)
.arg(info.stu_wechat);
if (!sql.exec(strsql)) {
QMessageBox::critical(nullptr, tr("Database Error"),
tr("Failed to insert data: %1").arg(sql.lastError().text()));
return false; // 返回 false 表示插入失败
}
}
m_db.commit();
return true; // 返回 true 表示插入成功
}
打包
样式打包
把我们的皮肤样式复制两份到当前目录,分别重名为dlg.css,main.css:
在dlg.css里只保留登录界面的样式,在main.css里只保留主界面的样式
在资源文件里把我们的所有资源都载入:
然后在主界面初始化的时候把我们的皮肤加载上:
数据库打包
数据库路径问题.我们把1端口打开,用当前目录下的路径,不要用绝对路径:
然后我们以debug方式打包我们的exe文件,打开QT安装目录下bin目录,在路径栏里输入"cmd",然后在dos窗户输入:"windeployqt.exe":
然后把我们的exe文件拖上去就开始打包了:
打包完成之后双击我们的exe文件发现运行不了:
这是QT的一个bug,有几个文件是不会打包的,需要我们手动打包.我们去bin目录下找到三个lib开头的文件,将其复制到打包好的exe文件同级目录下: