Qt实现学生学籍管理系统(文件存储)

记录

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窗口设计

  1. 登录界面(登录、注册、修改密码、忘记密码、退出)(这部分和学生界面设计有相似的地方,以后补充)
  2. 菜单界面
  3. 增加学生界面
  4. 修改学生界面(包括删除)
  5. 查找学生界面
  6. 对学生信息进行排序

项目设计:

因为我不会用数据库,而录入学生学籍又要使用省市区名,于是我尝试使用了将所有省市区写到txt文件中

数据来源:这里 或者 别点这里

我将所有的数据都录入txt文件了

录入的格式是:  行政编号 地区

Qt实现学生学籍管理系统(文件存储)_第1张图片

Qt实现学生学籍管理系统(文件存储)_第2张图片

Qt实现学生学籍管理系统(文件存储)_第3张图片

 

之后会把文件放到网盘的

1.建立项目

Qt实现学生学籍管理系统(文件存储)_第4张图片

建立一个空项目

 

Qt实现学生学籍管理系统(文件存储)_第5张图片

 

 

 Qt实现学生学籍管理系统(文件存储)_第6张图片

之后 点下一步就创建完成了一个空项目

2.界面的建立

把我们需要的窗口都加上

在新建的项目上右键选择AddNew

Qt实现学生学籍管理系统(文件存储)_第7张图片

 

 选择后Qt实现学生学籍管理系统(文件存储)_第8张图片

Qt实现学生学籍管理系统(文件存储)_第9张图片

这个MainControl就是用来把其他界面添加到一个QStackedLayout中(不知道的话可以看看文档 或者我下面会介绍)

 之后按这样的步骤再新建LoggingWidget(登录界面)、MenuWidget(菜单界面)、AddStudentWidget(增加学生界面)、ModifyStudentWidget(修改学生界面)、SearchStudentWidget(查找学生界面)、

SortStudentWidget(学生信息排序界面)

Qt实现学生学籍管理系统(文件存储)_第10张图片

 

注意要在pro文件中加上

1 QT +=widgets
2 QT +=core gui

之后在 Add new 一个main.cpp文件

 Qt实现学生学籍管理系统(文件存储)_第11张图片

 main.cpp

 1 #include"maincontrol.h" //下面要实例化一个MainControl对象 
 2 #include 
 3 
 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

 

Qt实现学生学籍管理系统(文件存储)_第12张图片

 

2)MenuWidget.ui

Qt实现学生学籍管理系统(文件存储)_第13张图片

3)AddStudentWidget.ui

Qt实现学生学籍管理系统(文件存储)_第14张图片

 

 4)ModifyStudentWidget.ui

Qt实现学生学籍管理系统(文件存储)_第15张图片

5)SearchStudentWidget.ui

Qt实现学生学籍管理系统(文件存储)_第16张图片

6)SortStudentWidget.ui

Qt实现学生学籍管理系统(文件存储)_第17张图片

这就是最终设计(大概)

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 右键->转到槽 中看到有许多信号 )

不过这个信号并不能直接的切换界面 需要编写自己的信号函数

 

Qt实现学生学籍管理系统(文件存储)_第18张图片

 

这个意思就是 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

View Code

menuwidget.cpp

View Code

 addstudentwidget.h

View Code

 

addstudentwidget.cpp

View Code

modifystudentwidget.h

View Code

modifystudentwidget.cpp

View Code

 

searchstudentwidget.h

View Code

 

searchstudentwidget.app

View Code

sortstudentwidget.h

View Code

 

sortstudentwidget.cpp

View Code

 

这样界面的切换就实现了 接下来将每个功能做好

 

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

View Code

 

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函数 官网上是这样的

 

Qt实现学生学籍管理系统(文件存储)_第19张图片

在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

具体的我就不写了(其实是不会) 大部分网上都有例子

 

美化后的:

Qt实现学生学籍管理系统(文件存储)_第20张图片

 

 Qt实现学生学籍管理系统(文件存储)_第21张图片

 

 Qt实现学生学籍管理系统(文件存储)_第22张图片

 

 当然 还存在一些bug(比如上图中horizontalHeader就有问题) 课设上的要求也没全完成 

不过 美化就这样了(比不上大佬的美化) 凑合看吧

转载于:https://www.cnblogs.com/57one/p/11273260.html

你可能感兴趣的:(Qt实现学生学籍管理系统(文件存储))