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文件了

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

 

之后会把文件放到网盘的

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 #include <QApplication>
 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

 

 

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 <QWidget>
#include<QStackedLayout>    
#include<QMessageBox>       //用于消息提示
#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 <QWidget>
#include<QLineEdit>
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 <QWidget>
 5 #include<QLineEdit>
 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<QString>
 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     QVector<Province>allProvince;               //利用QVector录入行政号及地区
 18     QList<QString>ProvinceList;                 //利用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     QVector<Province>allProvince;
 57     QList<QString>ProvinceList;
 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     QVector<Province>allProvince;
 85     QList<QString>ProvinceList;
 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<<ui->Name_Text->text()<<" "<<ui->ID_Text->text()<<" "<<ui->Math_Text->text()<<" "<<ui->English_Text->text()<<" "
117     <<ui->Programming_Text->text()<<" "<<ui->PE_Text->text()<<" "<<ui->Province->currentText()<<" "<<ui->City->currentText()<<
118     " "<<ui->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<QFile>
 4 #include<QTextStream>
 5 #include<QMessageBox>
 6 #include"studentinfo.h"
 7 class Global
 8 {
 9 public:
10     Global();
11 };
12 bool GetStudentInfo(QVector<StudentInfo> &allStudentInfo);
13 void WriteFile(QVector<StudentInfo>&allStudentInfo);
14 #endif // GLOBAL_H

 

 

global.cpp

 1 #include "global.h"
 2 
 3 Global::Global()
 4 {
 5 
 6 }
 7 bool GetStudentInfo(QVector<StudentInfo> &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<StudentInfo>&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<<it.GetName()<<" "<<it.GetID()<<" "<<it.GetMathScore()<<" "<<it.GetEngScore()<<" "<<
45         it.GetProScore()<<" "<<it.GetPEScore()<<" "<<it.GetProvince()<<" "<<it.GetCity()<<" "<<it.GetDistrict()<<endl;
46     }
47     file.close();
48 }

 

接下来就可以  完善其他功能了

 

 

6.ModifyStudentWidget

modifystudentwidget.h

 1 #ifndef SEARCHSTUDENTWIDGET_H
 2 #define SEARCHSTUDENTWIDGET_H
 3 
 4 #include <QWidget>
 5 #include<QFile>
 6 #include<QVector>
 7 #include<QMessageBox>
 8 #include<QDebug>
 9 #include<QString>
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     QVector<Province>allProvince;
 19     QList<QString>ProvinceList;
 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     QVector<StudentInfo>allStudentInfo;
 54     if(!GetStudentInfo(allStudentInfo))
 55         return ;
 56     bool flag=false;
 57     for(QVector<StudentInfo>::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     QVector<StudentInfo>allStudentInfo;
 92     if(!GetStudentInfo(allStudentInfo))
 93         return ;
 94     bool flag=false;
 95     for(QVector<StudentInfo>::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     QVector<Province>allProvince;
127     QList<QString>ProvinceList;
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     QVector<Province>allProvince;
155     QList<QString>ProvinceList;
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 <QWidget>
 5 #include<QFile>
 6 #include<QVector>
 7 #include<QMessageBox>
 8 #include<QDebug>
 9 #include<QString>
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     QVector<StudentInfo>allStudentInfo;
30     if(!GetStudentInfo(allStudentInfo))
31         return ;
32     bool flag=false;
33     for(QVector<StudentInfo>::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 <QWidget>
 5 #include<QFile>
 6 #include<QVector>
 7 #include<QMessageBox>
 8 #include<QDebug>
 9 #include<QButtonGroup>
10 #include<QtAlgorithms>
11 #include<QString>
12 #include<QTableWidgetItem>
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<<tr("姓名")<<tr("学号")<<tr("数学成绩")<<("英语成绩")<<tr("程序设计成绩")<<tr("体育成绩")<<tr("省")<<tr("市")<<tr("区");
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     QVector<StudentInfo>allStudentInfo;
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<allStudentInfo.size();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就有问题) 课设上的要求也没全完成 

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

posted @ 2019-07-30 22:36  57one  阅读(2471)  评论(0编辑  收藏  举报