记录
19:53 2019-07-30
在小学期学c++做完课设后萌生了把写完的课设放在博客上的想法,于是,我第一篇博客诞生了。
22:32:19 2019-07-30
下棋
16:04:56 2019-07-31
开始一边划水一边写 没写
14:51:18 2019-08-01
开始认真地写
16:54:55 2019-08-04
今天一定要写三分之二
19:31:00 2019-08-04
基本写完 之后会尝试加上数据库(没有)以及数据美化
19:45:41 2019-08-31
开始美化 我是鸽子
Qt实现学生学籍管理系统(文件存储)
对Qt初步了解:点这
看一看reference:点我
(本来就不会)大部分代码都是抄的博主suvvm:https://www.cnblogs.com/suvvm/p/10723449.html(这篇文章写的好)
github:https://github.com/57one/qt-learing/tree/master/StudentStatusSystem
课设要求:对学生信息录入,对信息的增删改排,可增加其他有用的功能
可使用Qt开发框架(别人都用我能不用吗),可以使用文件或数据库(大佬都用数据库去了)
学生属性设计:姓名、学号、数学成绩、英语成绩、程序设计成绩、体育成绩、籍贯(手动存信息真的是太痛苦了)
Qt窗口设计:
- 登录界面(登录、注册、修改密码、忘记密码、退出)(这部分和学生界面设计有相似的地方,以后补充)
- 菜单界面
- 增加学生界面
- 修改学生界面(包括删除)
- 查找学生界面
- 对学生信息进行排序
项目设计:
因为我不会用数据库,而录入学生学籍又要使用省市区名,于是我尝试使用了将所有省市区写到txt文件中
数据来源:这里 或者 别点这里
我将所有的数据都录入txt文件了
录入的格式是: 行政编号 地区
之后会把文件放到网盘的
1.建立项目
建立一个空项目
之后 点下一步就创建完成了一个空项目
2.界面的建立
把我们需要的窗口都加上
在新建的项目上右键选择AddNew
这个MainControl就是用来把其他界面添加到一个QStackedLayout中(不知道的话可以看看文档 或者我下面会介绍)
之后按这样的步骤再新建LoggingWidget(登录界面)、MenuWidget(菜单界面)、AddStudentWidget(增加学生界面)、ModifyStudentWidget(修改学生界面)、SearchStudentWidget(查找学生界面)、
SortStudentWidget(学生信息排序界面)
注意要在pro文件中加上
1 QT +=widgets
2 QT +=core gui
之后在 Add new 一个main.cpp文件
main.cpp
1 #include"maincontrol.h" //下面要实例化一个MainControl对象 2 #include3 4 /*QApplication类管理GUI程序的控制流和主要设置,基于Qwidget 处理Qwidget特有的初始化和结束收尾工作*/ 5 //QDialog、QMainWindow都继承于Qwidget 6 /*不管任何GUI程序,不管有多少个Window,只会有一个QApplication对象 7 QApplication管理了各种各样的应用程序的广泛资源、比如默认的字体和光标*/ 8 //简而言之 QApplication做了许多初始化工作,因此在其他UI对象创建前必须创建QApplication对象 9 10 int main(int argc, char *argv[])//程序的入口 main函数的2个参数 argc和argv argc是命令行的数量,argv存着命令行 11 { 12 QApplication a(argc, argv); //QApplication对象的创建 处理命令行参数 13 MainControl w; //MainControl对象的创建 14 w.show(); //利用show函数 变为可见 15 return a.exec(); //a.exec()进入事件循环 相当于把程序运行交给Qt处理,进入程序的循环状态 16 //return 0 会直接结束程序 17 }
如果不懂 a.exec()做了什么的话 可以看看:别点人家了啦
这样我们的程序就可以跑了 但啥都没有
接下来我们要做的就是设计界面 并设计界面切换 信号与槽(不明白可以看看文档)
3.界面设计
(其实这只是能看的样子,美化我以后再做)
点击对应的ui文件 进行设计
1)LoggingWidget.ui
2)MenuWidget.ui
3)AddStudentWidget.ui
4)ModifyStudentWidget.ui
5)SearchStudentWidget.ui
6)SortStudentWidget.ui
这就是最终设计(大概)
4.实现界面的切换
现在实现界面之间的切换 这就用到了Qt中的信号与槽
那先来了解一下信号与槽
先看看官方文档的解释 Signals & Slots
Qt用信号和槽代替了回调函数
简单的理解就是 用户的动作(或者说是满足某种条件)比如 点击产生了信号 这个信号传给槽函数(就是函数 接受到信号时会被调用)
比如在界面中有一个 关闭按钮 我点击后 产生了信号 与这个信号连接的关闭函数被调用(当然我提前把他们关联起来了)
信号可以由 图形界面对象发出 ,也可以由用户用 emit关键字发出信号(界面切换会用到emit)
要注意的是:槽函数的参数不多于信号的参数
首先了解一下界面切换的原理 首先我们把这么几个界面放在一个QStackedLayout中(这个QStackedLayout可以提供多界面切换,并且每次只会显示一个界面)
QStackLayout中有 AddWidget的方法 可以添加我们所需的界面(比如AddStudentWidget LoggingWidget之类的)
QStackLayout中有 一个槽函数:setCurrentIndex(int Index) 可以设置当前显示的界面 (这个Index就是你界面的标号 按照你添加界面的顺序从0开始,如果你没添加任何界面的话就是-1)
这样我们就可以通过 发射信号 来让槽函数改变当前显示界面
1)先把界面添加到一个QStackedLayout中
maincontrol.h
#ifndef MAINCONTROL_H
#define MAINCONTROL_H
#include
#include
#include //用于消息提示
#include"loggingwidget.h"
#include"menuwidget.h" #include"addstudentwidget.h" #include"modifystudentwidget.h" #include"searchstudentwidget.h" #include"sortstuwidget.h" namespace Ui { class mainControl; } class mainControl : public QWidget { Q_OBJECT private: QStackedLayout *stackedLayout; MenuWidget *menuwidget; AddStudentWidget *addstuwidget; ModifyStudentWidget *modifystuwidget; SearchStudentWidget *searchstuwidget; SortStuWidget *sortstuwidget; LoggingWidget *loggingWidget; public: explicit mainControl(QWidget *parent = nullptr); ~mainControl(); private: Ui::mainControl *ui; }; #endif // MAINCONTROL_H
maincontrol.cpp
#include "maincontrol.h"
#include "ui_maincontrol.h"
mainControl::mainControl(QWidget *parent) :
QWidget(parent),
ui(new Ui::mainControl)
{
ui->setupUi(this); //初始化界面
stackedLayout=new QStackedLayout; //QStackedLayoutlay对象的建立
loggingWidget=new LoggingWidget;
menuwidget=new MenuWidget; addstuwidget=new AddStudentWidget; modifystuwidget=new ModifyStudentWidget; searchstuwidget=new SearchStudentWidget; sortstuwidget=new SortStuWidget; stackedLayout->addWidget(loggingWidget); //向stackedlayout中添加界面 stackedLayout->addWidget(menuwidget); stackedLayout->addWidget(addstuwidget); stackedLayout->addWidget(modifystuwidget); stackedLayout->addWidget(searchstuwidget); stackedLayout->addWidget(sortstuwidget); setLayout(stackedLayout); //设置界面 } mainControl::~mainControl() { delete ui; }
这样就把所需要的界面添加到QstackedLayout中了
再看看setupUi和setLayout
从初始化列表中我们可以看到 ui是Ui::mainControl的指针 注意:这个Ui::mainControl类和mainControl类是两个不同的类(废话) 我们可以在maincontrol.h中看到Ui::mainControl是定义再命名空间Ui下的类。
ui->setupUi(this) 实现了窗体上组件的创建、属性设置、信号与槽的关联。 它按照我们在qt设计器中的设计用c++代码创建组件。
关于这个setLayout 对于我的程序来说 没了它还是能跑的 但会出现界面同时存在的情况 没有达到切换界面的效果。
接下来我们就利用信号与槽实现界面的切换
我们的要求是在界面中点击pushbutton然后进行界面切换
这个点击pushbutton也可以一个信号(我们可以在ui界面中选择一个pushbutton 右键->转到槽 中看到有许多信号 )
不过这个信号并不能直接的切换界面 需要编写自己的信号函数
这个意思就是 pushbutton的信号(qt已经存在的)->一个槽函数(利用qt创建)->我们的信号(自己写的)->界面切换的槽函数
我们先在loggingwidget.h中添加一个我们自己的信号
WQ#ifndef LOGGINGWIDGET_H
#define LOGGINGWIDGET_H
#include
#include
namespace Ui {
class LoggingWidget;
}
class LoggingWidget : public QWidget { Q_OBJECT public: explicit LoggingWidget(QWidget *parent = nullptr); ~LoggingWidget(); signals: void display(int number); //我们的信号 private: Ui::LoggingWidget *ui; }; #endif // LOGGINGWIDGET_H
我们的信号是 在pushbutton按下 后在槽函数中发出的 我们在loggingwidget.ui中找到 登录pushbutton 选择右键->转到槽 选择click() 函数 再点击ok就会自动生成一个槽函数
这个槽函数的名字是
on_btnLogging_clicked();
这个btnLogging就是我 登录pushbutton的名称
在函数定义中发射我们的信号就可以了
#include "loggingwidget.h"
#include "ui_loggingwidget.h"
LoggingWidget::LoggingWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::LoggingWidget)
{
ui->setupUi(this);
ui->UserName_Text->setPlaceholderText("请输入用户名"); ui->UserPasd_Text->setPlaceholderText("请输入密码"); } LoggingWidget::~LoggingWidget() { delete ui; } void LoggingWidget::on_btnLogging_clicked() { emit display(1); //我们的信号 里面的数字是根据添加界面的顺序来的 }
这样就完成了 pushbutton的信号(qt已经存在的)->一个槽函数(利用qt创建)->我们的信号(自己写的)
接下来将的信号与槽函数连接起来
maincontrol.cpp
1 #include "maincontrol.h"
2 #include "ui_maincontrol.h"
3
4 mainControl::mainControl(QWidget *parent) :
5 QWidget(parent),
6 ui(new Ui::mainControl)
7 {
8 ui->setupUi(this); //初始化界面
9 stackedLayout=new QStackedLayout; //QStackedLayoutlay对象的建立
10 loggingWidget=new LoggingWidget;
11 menuwidget=new MenuWidget; 12 addstuwidget=new AddStudentWidget; 13 modifystuwidget=new ModifyStudentWidget; 14 searchstuwidget=new SearchStudentWidget; 15 sortstuwidget=new SortStuWidget; 16 stackedLayout->addWidget(loggingWidget); //向stackedlayout中添加界面 17 stackedLayout->addWidget(menuwidget); 18 stackedLayout->addWidget(addstuwidget); 19 stackedLayout->addWidget(modifystuwidget); 20 stackedLayout->addWidget(searchstuwidget); 21 stackedLayout->addWidget(sortstuwidget); 22 setLayout(stackedLayout); //设置界面 23 connect(loggingWidget,&LoggingWidget::display,stackedLayout,&QStackedLayout::setCurrentIndex); 24 mainControl::~mainControl() 25 { 26 delete ui; 27 }
这个connec函数将信号与槽连接
connect函数的原型 bool QObject::connect(const QObject* sender,const char * signal,const QObject * receiver,const char * member)[static]
上面23行 意思是loggingWidget 发射的display信号 会被 stackLayout 的setCurrentIndex接受到
display参数与setCurrentIndex的参数都是int型 所以setCurrenIndex可以实现切换界面
之后就是相似的实现其他界面切换(包括退出)
loggingwidget.h
1 #ifndef LOGGINGWIDGET_H
2 #define LOGGINGWIDGET_H
3
4 #include
5 #include
6 namespace Ui {
7 class LoggingWidget;
8 }
9
10 class LoggingWidget : public QWidget
11 { 12 Q_OBJECT 13 public: 14 explicit LoggingWidget(QWidget *parent = nullptr); 15 ~LoggingWidget(); 16 signals: 17 void display(int number); 18 private slots: 19 void on_btnLogging_clicked(); 20 void on_btnExit_clicked(); 21 22 private: 23 Ui::LoggingWidget *ui; 24 }; 25 26 #endif // LOGGINGWIDGET_H
loggingwidget.cpp
#include "loggingwidget.h"
#include "ui_loggingwidget.h"
LoggingWidget::LoggingWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::LoggingWidget)
{
ui->setupUi(this);
ui->UserName_Text->setPlaceholderText("请输入用户名"); ui->UserPasd_Text->setPlaceholderText("请输入密码"); } LoggingWidget::~LoggingWidget() { delete ui; } void LoggingWidget::on_btnLogging_clicked() { emit display(1); } void LoggingWidget::on_btnExit_clicked() { QApplication::exit(); }
这个exit就是使QApplication退出主事件循环
menuwidget.h
menuwidget.cpp
addstudentwidget.h
addstudentwidget.cpp
modifystudentwidget.h
modifystudentwidget.cpp
searchstudentwidget.h
searchstudentwidget.app
sortstudentwidget.h
sortstudentwidget.cpp
这样界面的切换就实现了 接下来将每个功能做好
5.AddStudnetWidget
先实现用combox三级联动省市区
在开始的时候我已经把所有的信息都录入到文件中了
combobox有个信号currentIndexChanged 可以传递改变的text 我们可以根据text文本内容打开相应的文件
因为录入的时候是 行政编号加地区 录入的 所以省 这个类 有2个变量
province.h
1 #ifndef PROVINCE_H
2 #define PROVINCE_H
3 #include
4 class Province
5 {
6 private:
7 QString ProvinceNumber,ProvinceName;
8 public: 9 Province(){} 10 Province(QString ProvinceNumber,QString ProvinceName):ProvinceNumber(ProvinceNumber),ProvinceName(ProvinceName){} 11 QString GetProName(){return ProvinceName;} 12 QString GetProNumber(){return ProvinceNumber;} 13 }; 14 15 #endif // PROVINCE_H
省 市 区 在文档中都是 行政编号加地区 所以我就没有再新建 市 类 和 区 类 直接用省的对象来 操作
把学生类也定义了 下面录入信息会用
studentinfo.h
1 #ifndef STUDENTINFO_H
2 #define STUDENTINFO_H
3 #include"QString"
4 class StudentInfo
5 {
6 private:
7 QString Name;
8 int ID,MathScore,EngScore,ProScore,PEScore; 9 QString Province,City,District; 10 public: 11 StudentInfo(){} 12 StudentInfo(QString Name,int ID,int MathScore,int EngScore,int ProScore, 13 int PEScore,QString Province,QString City, 14 QString District):Name(Name),ID(ID),MathScore(MathScore),EngScore(EngScore),ProScore(ProScore), 15 PEScore(PEScore),Province(Province),City(City),District(District){} 16 QString GetName()const{return Name;} 17 int GetID()const{return ID;} 18 int GetMathScore()const{return MathScore;} 19 int GetEngScore()const{return EngScore;} 20 int GetProScore()const{return ProScore;} 21 int GetPEScore()const{return PEScore;} 22 QString GetProvince()const{return Province;} 23 QString GetCity()const{return City;} 24 QString GetDistrict()const{return District;} 25 void SetName(QString name){Name=name;} 26 void SetMathScore(int mathScore){MathScore=mathScore;} 27 void SetEngScore(int engScore){EngScore=engScore;} 28 void SetProScoer(int proScore){ProScore=proScore;} 29 void SetPEScore(int peScore){PEScore=peScore;} 30 void SetProvince(QString province){Province=province;} 31 void SetCity(QString city){City=city;} 32 void SetDistrict(QString district){District=district;} 33 }; 34 #endif // STUDENTINFO_H
addstudentwidget.h
addstudentwidget.h
1 #include "addstudentwidget.h"
2 #include "ui_addstudentwidget.h"
3
4 AddStudentWidget::AddStudentWidget(QWidget *parent) :
5 QWidget(parent),
6 ui(new Ui::AddStudentWidget)
7 {
8 ui->setupUi(this);
9 QFile file("F:\\country\\china\\provinces.txt"); // 打开省的文档
10 file.open(QIODevice::ReadOnly|QIODevice::Text); //打开方式 readonly只读 text以文本形式打开
11 if(!file.isOpen()) //判断文件打开是否成功
12 { 13 QMessageBox::about(NULL,"错误","文件打开失败"); 14 return ; 15 } 16 QTextStream inp(&file); //利用QTextStream读写文件 17 QVectorallProvince; //利用QVector录入行政号及地区 18 QListProvinceList; //利用QList录入地区 19 bool have=false; //检测是否录入信息 20 while(!inp.atEnd()) 21 { 22 have=true; 23 QString ProvinceNumber,ProvinceName; 24 inp>>ProvinceNumber>>ProvinceName; 25 allProvince.push_back(Province(ProvinceNumber,ProvinceName)); 26 ProvinceList.append(ProvinceName); 27 } 28 if(have) //这里这个没有也可以 29 allProvince.pop_back(); 30 file.close(); 31 ui->Province->addItems(ProvinceList); //设置combobox的items 32 } 33 34 AddStudentWidget::~AddStudentWidget() 35 { 36 delete ui; 37 } 38 39 void AddStudentWidget::on_btnQuit_clicked() 40 { 41 emit display(1); 42 } 43 44 void AddStudentWidget::on_Province_currentIndexChanged(const QString &arg1) 45 { 46 ui->City->clear(); //清空市combobox的内容 47 QString DatAddress="F:\\country\\china\\"+arg1+"\\"+arg1+"Cities.txt"; //利用省combobox的改变来访问市文档 48 QFile file(DatAddress); 49 file.open(QIODevice::ReadOnly|QIODevice::Text); 50 if(!file.isOpen()) 51 { 52 QMessageBox::about(NULL,"错误","文件打开失败"); 53 return ; 54 } 55 QTextStream inp(&file); 56 QVectorallProvince; 57 QListProvinceList; 58 bool have=false; 59 while(!inp.atEnd()) 60 { 61 QString ProvinceNumber,ProvinceName; 62 inp>>ProvinceNumber>>ProvinceName; 63 allProvince.push_back(Province(ProvinceNumber,ProvinceName)); 64 ProvinceList.append(ProvinceName); 65 } 66 if(have) 67 allProvince.pop_back(); 68 file.close(); 69 ui->City->addItems(ProvinceList); 70 } 71 72 void AddStudentWidget::on_City_currentIndexChanged(const QString &arg1) 73 { 74 ui->District->clear(); 75 QString DatAddress="F:\\country\\china\\"+ui->Province->currentText()+"\\"+ui->Province->currentText()+"Cities\\"+arg1+".txt"; 76 QFile file(DatAddress); //利用省和市来访问区文档 77 file.open(QIODevice::ReadOnly|QIODevice::Text); 78 /*if(!file.isOpen()) 79 { 80 QMessageBox::about(NULL,"错误","文件打开失败"); 81 return ; 82 }*/ 83 QTextStream inp(&file); 84 QVectorallProvince; 85 QListProvinceList; 86 bool have=false; 87 while(!inp.atEnd()) 88 { 89 QString ProvinceNumber,ProvinceName; 90 inp>>ProvinceNumber>>ProvinceName; 91 allProvince.push_back(Province(ProvinceNumber,ProvinceName)); 92 ProvinceList.append(ProvinceName); 93 } 94 if(have) 95 allProvince.pop_back(); 96 file.close(); 97 ui->District->addItems(ProvinceList); 98 } 99 void AddStudentWidget::on_btnAdd_clicked() 100 { 101 if(ui->Name_Text->text()==""||ui->ID_Text->text()==""||ui->Math_Text->text()==""|| 102 ui->English_Text->text()==""||ui->Programming_Text->text()==""|| 103 ui->PE_Text->text()=="") 104 { 105 QMessageBox::about(NULL,"错误","存在空项"); //存在空项进行报错 106 return ; 107 } 108 QFile file("StudentInfo.txt"); //打开文档 也可以使用绝对路径 109 file.open(QIODevice::WriteOnly|QIODevice::Text|QIODevice::Append); 110 while (!file.isOpen()) 111 { 112 QMessageBox::about(NULL,"错误","文件打开失败"); 113 return ; 114 } 115 QTextStream outp(&file); 116 outp<Name_Text->text()<<" "<ID_Text->text()<<" "<Math_Text->text()<<" "<English_Text->text()<<" " 117 <Programming_Text->text()<<" "<PE_Text->text()<<" "<Province->currentText()<<" "<City->currentText()<< 118 " "<District->currentText()<<endl; 119 file.close(); 120 QMessageBox::about(NULL,"反馈","录入成功"); 121 ui->Name_Text->clear(); //清空plaintext 122 ui->ID_Text->clear(); 123 ui->Math_Text->clear(); 124 ui->English_Text->clear(); 125 ui->Programming_Text->clear(); 126 ui->PE_Text->clear(); 127 ui->Province->setCurrentText("北京市"); //设置为默认 128 }
学生信息录入使用 QTextStream和QFile结合的方式 QTextStream 与 IO 读写设备结合,为数据读写提供了一些方便的方法的类
其中QIODevice决定了文件的打开方式
在读入省市区时我用了QVector和QList 其实QVector没有实际运用,如果要使用行政号可能会用(以后的事)
但在使用QVectort时发现了一个问题
读入数据时 QVector使用的push_back 之后QVector进行了pop_back()(其实这里有没有无所谓pop无所谓 后面其它界面代码设计时 得有
我查询了 循环中 的atend函数 官网上是这样的
在addstudentwidget中是没有问题的
但在后面的代码中(modifystudentwidgt searchstudentwidget中缺了这个pop是不行的 会多出一行空的数据
18:54:08 2019-08-01 该问题未解决 怀疑是\r\n导致的
这样大概完成了addstudentwidget的设计
剩下的还有modifystudetwidget searchstudentwidget sortstudentwidget
这三个都是将数据先读入QVector中 然后对数据进行操作 所以可以加一个头文件 global.h和global.cpp 里面写将数据从文件读入 QVector 和将数据写入文件(modifystudentwidget会用)
global.h
1 #ifndef GLOBAL_H
2 #define GLOBAL_H
3 #include
4 #include
5 #include
6 #include"studentinfo.h"
7 class Global
8 {
9 public:
10 Global();
11 }; 12 bool GetStudentInfo(QVector &allStudentInfo); 13 void WriteFile(QVector&allStudentInfo); 14 #endif // GLOBAL_H
global.cpp
1 #include "global.h"
2
3 Global::Global()
4 {
5
6 }
7 bool GetStudentInfo(QVector &allStudentInfo)
8 {
9 QFile file("StudentInfo.txt"); 10 file.open(QIODevice::ReadOnly|QIODevice::Text); 11 while (!file.isOpen()) { 12 QMessageBox::about(NULL,"错误","文件打开失败"); 13 return false; 14 } 15 QTextStream inp(&file); 16 bool have=false; 17 while(!inp.atEnd()) 18 { 19 have=true; 20 QString name,province,city,district; 21 int id,math,english,programming,pe; 22 inp>>name>>id>>math>>english>>programming>>pe>>province>>city>>district; 23 allStudentInfo.push_back(StudentInfo(name,id,math,english,programming,pe,province,city,district)); 24 } 25 if(have) 26 { 27 allStudentInfo.pop_back(); 28 } 29 file.close(); 30 return true; 31 } 32 void WriteFile(QVector&allStudentInfo) 33 { 34 QFile file("StudentInfo.txt"); 35 file.open(QIODevice::WriteOnly|QIODevice::Text|QIODevice::Truncate); 36 while (!file.isOpen()) { 37 QMessageBox::about(NULL,"错误","文件打开失败"); 38 return ; 39 } 40 QTextStream outp(&file); 41 for(auto it: allStudentInfo) 42 { 43 QMessageBox::about(NULL,"",it.GetName()); 44 outp<endl; 46 } 47 file.close(); 48 }
接下来就可以 完善其他功能了
6.ModifyStudentWidget
modifystudentwidget.h
1 #ifndef SEARCHSTUDENTWIDGET_H
2 #define SEARCHSTUDENTWIDGET_H
3
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include"studentinfo.h"
11 namespace Ui {
12 class SearchStudentWidget;
13 }
14
15 class SearchStudentWidget : public QWidget
16 { 17 Q_OBJECT 18 19 public: 20 explicit SearchStudentWidget(QWidget *parent = nullptr); 21 ~SearchStudentWidget(); 22 signals: 23 void display(int number); 24 private slots: 25 void on_btnQuit_clicked(); 26 27 void on_btnSearch_clicked(); 28 29 private: 30 Ui::SearchStudentWidget *ui; 31 }; 32 33 #endif // SEARCHSTUDENTWIDGET_H
modifystudentwidget.cpp
1 #include "modifystudentwidget.h"
2 #include "ui_modifystudentwidget.h"
3 #include"global.h"
4 #include"province.h"
5 ModifyStudentWidget::ModifyStudentWidget(QWidget *parent) :
6 QWidget(parent),
7 ui(new Ui::ModifyStudentWidget)
8 {
9 ui->setupUi(this);
10 QFile file("F:\\country\\china\\provinces.txt"); 11 file.open(QIODevice::ReadOnly|QIODevice::Text); 12 if(!file.isOpen()) 13 { 14 QMessageBox::about(NULL,"错误","文件打开失败"); 15 return ; 16 } 17 QTextStream inp(&file); 18 QVectorallProvince; 19 QListProvinceList; 20 bool have=false; 21 while(!inp.atEnd()) 22 { 23 QString ProvinceNumber,ProvinceName; 24 inp>>ProvinceNumber>>ProvinceName; 25 allProvince.push_back(Province(ProvinceNumber,ProvinceName)); 26 ProvinceList.append(ProvinceName); 27 } 28 if(have) 29 allProvince.pop_back(); 30 file.close(); 31 ui->Province->addItems(ProvinceList); 32 } 33 34 ModifyStudentWidget::~ModifyStudentWidget() 35 { 36 delete ui; 37 } 38 39 void ModifyStudentWidget::on_btnQuit_clicked() 40 { 41 emit display(1); 42 } 43 44 void ModifyStudentWidget::on_btnModify_clicked() 45 { 46 if(ui->Name_Text->text()==""||ui->ID_Text->text()==""||ui->Math_Text->text()==""|| 47 ui->English_Text->text()==""||ui->Programming_Text->text()==""|| 48 ui->PE_Text->text()=="") 49 { 50 QMessageBox::about(NULL,"错误","存在空项"); 51 return ; 52 } 53 QVectorallStudentInfo; 54 if(!GetStudentInfo(allStudentInfo)) 55 return ; 56 bool flag=false; 57 for(QVector::iterator it=allStudentInfo.begin();it!=allStudentInfo.end();it++) //为什么没进入????? 58 { //进入了 但我啥也没改啊 59 if(it->GetID()==ui->ID_Text->text().toInt()) 60 { 61 flag=true; 62 it->SetName(ui->Name_Text->text()); 63 it->SetMathScore(ui->Math_Text->text().toInt()); 64 it->SetEngScore(ui->English_Text->text().toInt()); 65 it->SetProScoer(ui->Programming_Text->text().toInt()); 66 it->SetPEScore(ui->PE_Text->text().toInt()); 67 it->SetProvince(ui->Province->currentText()); 68 it->SetCity(ui->City->currentText()); 69 it->SetDistrict(ui->District->currentText()); 70 break; 71 } 72 } 73 if(flag) 74 { 75 QMessageBox::about(NULL,"反馈","修改成功"); 76 WriteFile(allStudentInfo); 77 } 78 else 79 QMessageBox::about(NULL,"反馈","id不存在"); 80 ui->ID_Text->clear(); 81 } 82 83 void ModifyStudentWidget::on_btnDelete_clicked() 84 { 85 86 if(ui->ID_Text->text()=="") 87 { 88 QMessageBox::about(NULL,"错误","id不得为空"); 89 return ; 90 } 91 QVectorallStudentInfo; 92 if(!GetStudentInfo(allStudentInfo)) 93 return ; 94 bool flag=false; 95 for(QVector::iterator it=allStudentInfo.begin();it!=allStudentInfo.end();it++) 96 { 97 if(it->GetID()==ui->ID_Text->text().toInt()) 98 { 99 flag=true; 100 allStudentInfo.erase(it); 101 break; 102 } 103 } 104 if(flag) 105 { 106 QMessageBox::about(NULL,"反馈","删除成功"); 107 WriteFile(allStudentInfo); 108 } 109 else 110 QMessageBox::about(NULL,"反馈","id不存在"); 111 ui->ID_Text->clear(); 112 } 113 114 void ModifyStudentWidget::on_Province_currentIndexChanged(const QString &arg1) 115 { 116 ui->City->clear(); 117 QString DatAddress="F:\\country\\china\\"+arg1+"\\"+arg1+"Cities.txt"; 118 QFile file(DatAddress); 119 file.open(QIODevice::ReadOnly|QIODevice::Text); 120 if(!file.isOpen()) 121 { 122 QMessageBox::about(NULL,"错误","文件打开失败"); 123 return ; 124 } 125 QTextStream inp(&file); 126 QVectorallProvince; 127 QListProvinceList; 128 bool have=false; 129 while(!inp.atEnd()) 130 { 131 QString ProvinceNumber,ProvinceName; 132 inp>>ProvinceNumber>>ProvinceName; 133 allProvince.push_back(Province(ProvinceNumber,ProvinceName)); 134 ProvinceList.append(ProvinceName); 135 } 136 if(have) 137 allProvince.pop_back(); 138 file.close(); 139 ui->City->addItems(ProvinceList); 140 } 141 142 void ModifyStudentWidget::on_City_currentIndexChanged(const QString &arg1) 143 { 144 ui->District->clear(); 145 QString DatAddress="F:\\country\\china\\"+ui->Province->currentText()+"\\"+ui->Province->currentText()+"Cities\\"+arg1+".txt"; 146 QFile file(DatAddress); 147 file.open(QIODevice::ReadOnly|QIODevice::Text); 148 /*if(!file.isOpen()) 149 { 150 QMessageBox::about(NULL,"错误","文件打开失败"); 151 return ; 152 }*/ 153 QTextStream inp(&file); 154 QVectorallProvince; 155 QListProvinceList; 156 bool have=false; 157 while(!inp.atEnd()) 158 { 159 QString ProvinceNumber,ProvinceName; 160 inp>>ProvinceNumber>>ProvinceName; 161 allProvince.push_back(Province(ProvinceNumber,ProvinceName)); 162 ProvinceList.append(ProvinceName); 163 } 164 if(have) 165 allProvince.pop_back(); 166 file.close(); 167 ui->District->addItems(ProvinceList); 168 }
7.SearchStudentWidget
searchstudentwidget.h
1 #ifndef SEARCHSTUDENTWIDGET_H
2 #define SEARCHSTUDENTWIDGET_H
3
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include"studentinfo.h"
11 namespace Ui {
12 class SearchStudentWidget;
13 }
14
15 class SearchStudentWidget : public QWidget
16 { 17 Q_OBJECT 18 19 public: 20 explicit SearchStudentWidget(QWidget *parent = nullptr); 21 ~SearchStudentWidget(); 22 signals: 23 void display(int number); 24 private slots: 25 void on_btnQuit_clicked(); 26 27 void on_btnSearch_clicked(); 28 29 private: 30 Ui::SearchStudentWidget *ui; 31 }; 32 33 #endif // SEARCHSTUDENTWIDGET_H
searchstudentwidget.cpp
1 #include "searchstudentwidget.h"
2 #include "ui_searchstudentwidget.h"
3 #include "global.h"
4
5 SearchStudentWidget::SearchStudentWidget(QWidget *parent) :
6 QWidget(parent),
7 ui(new Ui::SearchStudentWidget)
8 {
9 ui->setupUi(this);
10 } 11 12 SearchStudentWidget::~SearchStudentWidget() 13 { 14 delete ui; 15 } 16 17 void SearchStudentWidget::on_btnQuit_clicked() 18 { 19 emit display(1); 20 } 21 22 void SearchStudentWidget::on_btnSearch_clicked() 23 { 24 if(ui->ID_Text->text()=="") 25 { 26 QMessageBox::about(NULL,"反馈","id为空"); 27 return ; 28 } 29 QVectorallStudentInfo; 30 if(!GetStudentInfo(allStudentInfo)) 31 return ; 32 bool flag=false; 33 for(QVector::iterator it=allStudentInfo.begin();it!=allStudentInfo.end();it++) 34 { 35 if(it->GetID()==ui->ID_Text->text().toInt()) 36 { 37 flag=true; 38 ui->Name_Label->setText(it->GetName()); 39 ui->Math_Label->setText(QString::number(it->GetMathScore())); 40 ui->Eng_Label->setText(QString::number(it->GetEngScore())); 41 ui->Pro_Label->setText(QString::number(it->GetProScore())); 42 ui->PE_Label->setText(QString::number(it->GetPEScore())); 43 ui->Province->setText(it->GetProvince()); 44 ui->City->setText(it->GetCity()); 45 ui->District->setText(it->GetDistrict()); 46 break; 47 } 48 } 49 if(flag) 50 QMessageBox::about(NULL,"反馈","查找成功"); 51 else 52 QMessageBox::about(NULL,"反馈","id不存在"); 53 54 }
8.SortStudentWidget
sortstudentwidget.h
1 #ifndef SORTSTUWIDGET_H
2 #define SORTSTUWIDGET_H
3
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include"studentinfo.h"
14 namespace Ui {
15 class SortStuWidget;
16 }
17
18 class SortStuWidget : public QWidget
19 { 20 Q_OBJECT 21 private: 22 QButtonGroup *buttonGroup; 23 QStringList stringList; 24 public: 25 explicit SortStuWidget(QWidget *parent = nullptr); 26 ~SortStuWidget(); 27 signals: 28 void display(int number); 29 private slots: 30 void on_pushButton_2_clicked(); 31 32 void on_btnSort_clicked(); 33 34 private: 35 Ui::SortStuWidget *ui; 36 }; 37 38 #endif // SORTSTUWIDGET_H
sortstudentwidget.cpp
1 #include "sortstudentwidget.h"
2 #include "ui_sortstuwidget.h"
3 #include"global.h"
4 SortStuWidget::SortStuWidget(QWidget *parent) :
5 QWidget(parent),
6 ui(new Ui::SortStuWidget)
7 {
8 ui->setupUi(this);
9 buttonGroup=new QButtonGroup; 10 buttonGroup->addButton(ui->rbtnMath,0); 11 buttonGroup->addButton(ui->rbtnEnglish,1); 12 buttonGroup->addButton(ui->rbtnProgramming,2); 13 buttonGroup->addButton(ui->rbtnPE,3); 14 buttonGroup->addButton(ui->rbtnProvince,4); 15 buttonGroup->addButton(ui->rbtnID,5); 16 buttonGroup->setExclusive(true); 17 ui->tableWidget->setColumnCount(9); 18 stringList<); 19 ui->tableWidget->setHorizontalHeaderLabels(stringList); 20 ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); 21 ui->tableWidget->setRowCount(1); 22 } 23 24 SortStuWidget::~SortStuWidget() 25 { 26 delete ui; 27 } 28 29 void SortStuWidget::on_pushButton_2_clicked() 30 { 31 emit display(1); 32 ui->tableWidget->clearContents(); 33 ui->tableWidget->setRowCount(1); 34 } 35 bool cmp_Math(const StudentInfo &a,const StudentInfo &b) 36 { 37 return a.GetMathScore()>b.GetMathScore(); 38 } 39 bool cmp_English(const StudentInfo &a,const StudentInfo &b) 40 { 41 return a.GetEngScore()>b.GetEngScore(); 42 } 43 bool cmp_Programming(const StudentInfo &a,const StudentInfo &b) 44 { 45 return a.GetProScore()>b.GetProScore(); 46 } 47 bool cmp_PE(const StudentInfo &a,const StudentInfo &b) 48 { 49 return a.GetPEScore()>b.GetPEScore(); 50 } 51 bool cmp_ID(const StudentInfo &a,const StudentInfo &b) 52 { 53 return a.GetID()>b.GetID(); 54 } 55 bool cmp_Province(const StudentInfo &a,const StudentInfo &b) 56 { 57 return a.GetProvince()>b.GetProvince(); 58 } 59 void SortStuWidget::on_btnSort_clicked() 60 { 61 QVectorallStudentInfo; 62 if(!GetStudentInfo(allStudentInfo)) 63 return ; 64 int tag=buttonGroup->checkedId(); 65 switch (tag) 66 { 67 case 0:std::sort(allStudentInfo.begin(),allStudentInfo.end(),cmp_Math);break; 68 case 1:std::sort(allStudentInfo.begin(),allStudentInfo.end(),cmp_English);break; 69 case 2:std::sort(allStudentInfo.begin(),allStudentInfo.end(),cmp_Programming);break; 70 case 3:std::sort(allStudentInfo.begin(),allStudentInfo.end(),cmp_PE);break; 71 case 4:std::sort(allStudentInfo.begin(),allStudentInfo.end(),cmp_Province);break; 72 case 5:std::sort(allStudentInfo.begin(),allStudentInfo.end(),cmp_ID);break; 73 } 74 ui->tableWidget->setSortingEnabled(false); 75 ui->tableWidget->setRowCount(allStudentInfo.size()); //设置行数与学生数相同 否则添加后显示不出来 76 for(int i=0;i) 77 { 78 ui->tableWidget->setItem(i,0,new QTableWidgetItem(allStudentInfo.at(i).GetName())); 79 ui->tableWidget->setItem(i,1,new QTableWidgetItem(QString::number(allStudentInfo.at(i).GetID()))); 80 ui->tableWidget->setItem(i,2,new QTableWidgetItem(QString::number(allStudentInfo.at(i).GetMathScore()))); 81 ui->tableWidget->setItem(i,3,new QTableWidgetItem(QString::number(allStudentInfo.at(i).GetEngScore()))); 82 ui->tableWidget->setItem(i,4,new QTableWidgetItem(QString::number(allStudentInfo.at(i).GetProScore()))); 83 ui->tableWidget->setItem(i,5,new QTableWidgetItem(QString::number(allStudentInfo.at(i).GetPEScore()))); 84 ui->tableWidget->setItem(i,6,new QTableWidgetItem(allStudentInfo.at(i).GetProvince())); 85 ui->tableWidget->setItem(i,7,new QTableWidgetItem(allStudentInfo.at(i).GetCity())); 86 ui->tableWidget->setItem(i,8,new QTableWidgetItem(allStudentInfo.at(i).GetDistrict())); 87 } 88 ui->tableWidget->setSortingEnabled(true); 89 }
这样基本完成了学生学籍管理系统
声明:我这个大部分都抄了博主suvvm的 Qt5——从零开始的学生管理系统 而且我写的也没有该博主详细
美化的话 听说qss和css差不多 (不一样也没关系 反正我都不会)
先在网上找了在哪写QSS:具体教程的话:https://blog.csdn.net/kidults/article/details/53482971
具体的我就不写了(其实是不会) 大部分网上都有例子
美化后的:
当然 还存在一些bug(比如上图中horizontalHeader就有问题) 课设上的要求也没全完成
不过 美化就这样了(比不上大佬的美化) 凑合看吧
转载于:https://www.cnblogs.com/57one/p/11273260.html
你可能感兴趣的:(Qt实现学生学籍管理系统(文件存储))