记录

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

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<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

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就有问题) 课设上的要求也没全完成

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

Qt实现学生学籍管理系统(文件存储)的更多相关文章

  1. [C语言练习]学生学籍管理系统

    /** * @copyright 2012 Chunhui Wang * * wangchunhui@wangchunhui.cn * * 学生学籍管理系统(12.06) */ #include &l ...

  2. “石家庄铁道大学软件工程系学生学籍管理系统2019版”java小程序制作分享

    首先附上完整代码: import java.util.Scanner; public class SocreInformation { public SocreInformation(){}; pub ...

  3. C++实现控制台学生学籍管理系统

    操作流程 创建文件 创建管理类 ​ 管理类负责的内容如下: 提供与用户的沟通菜单界面 实现对职工增删改查的操作 数组数据与文件的读写交互 菜单功能实现 在StudentManager.h中定义Show ...

  4. Java 石家庄铁道大学软件工程系 学生学籍管理系统 2019 版

    本系统的作用是简单实现一些学生成绩管理操作:录入,修改,绩点计算,以及系统退出等. 首先建一个主函数实现界面的实现,然后建一个数据类用来定义存放数据.之后建立一个工具类,用来实现所有要进行的操作.首先 ...

  5. 【C】C语言大作业——学生学籍管理系统

    文章目录 学生管理系统 界面 主界面 登陆界面 注册界面 管理界面 学生界面 退出界面 链接 注意 学生管理系统 学C语言时写的一个大作业,弄了一个带图形界面的,使用的是VS配合EasyX图形库进行实 ...

  6. 【C语言期末实训】学生学籍管理系统

    目录: 一,设计要求 ,总体要求: ,具体功能: 二,设计框架 三,程序代码 ,声明函数和头文件 ,声明结构体 ,声明全局变量 ,主体启动函数 ,主菜单函数 ,创建学生档案函数 ,编辑学生档案函数 , ...

  7. 还是把一个课程设计作为第一篇文章吧——学生学籍管理系统(C语言)

    #include <stdio.h> #include<stdlib.h> #include<string.h> typedef struct student { ...

  8. java学生成绩管理系统

                                                       信1805-1 20183590 田庆辉             石家庄铁道大学 2019 年秋季 ...

  9. JAVA之学生信息管理系统

    StudentManager系统 系统的数据: 变量 stunumber 为字符串类型 String,用于存储学生的学号(有 8 位数字组成) 变量 name 为字符串类型 String,用于存储学生 ...

随机推荐

  1. Nginx之负载均衡配置(二)

    前文我们聊到了nginx作为负载均衡的配置,前端nginx作为调度器调度http或https请求,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12458159 ...

  2. 基于正向扫描的并行区间连接平面扫描算法(IEEE论文)

    作者: Panagiotis Bouros ∗Department of Computer ScienceAarhus University, Denmarkpbour@cs.au.dkNikos M ...

  3. openwrt 外挂usb 网卡 RTL8188CU 及添加 RT5572 kernel支持

    RT5572 原来叫 Ralink雷凌 现在被 MTK 收购了,淘宝上买的很便宜50块邮,2.4 5G 双频.在 win10 上插了试试,果然是支持 5G.这上面写着 飞荣 是什么牌子,有知道的和我说 ...

  4. ubuntu16.04 + caffe + SSD + gpu 安装

    昨天我们买好了硬件,今天我们开始安装caffe了,我本人安装过caffe不下10次,每次都是一大堆问题,后来终于总结了关键要点,就是操作系统. 1. 千万不要用ubuntu17.10来安装, 2. 最 ...

  5. 测试必知必会系列- Linux常用命令 - cp

    21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html 复制文 ...

  6. 基于均值坐标(Mean-Value Coordinates)的图像融合算法的优化实现

    目录 1. 概述 2. 实现 2.1. 原理 2.2. 核心代码 2.3. 第二种优化 3. 结果 1. 概述 我在之前的文章<基于均值坐标(Mean-Value Coordinates)的图像 ...

  7. 小白学 Python 数据分析(17):Matplotlib(二)基础操作

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  8. 【Weiss】【第03章】练习3.17:懒惰删除

    [练习3.17] 不同于我们已经给出的删除方法,另一种是使用懒惰删除的方法. 为了删除一个元素,我们只标记上该元素被删除的信息(使用一个附加的位域). 表中被删除和非被删除的元素个数作为数据结构的一部 ...

  9. Python基础 | 关于“循环”那些事

    目录 for 循环 list range enumerate zip while 循环 while相当于if时 while充当for和if的混合体 泛循环 列表解析 map 迭代器 生成器 循环的跳出 ...

  10. django之forms组件,cookie&session

    forms组件 先自己实现注册功能,并且对用户输入的信息加限制条件如果用户输入的信息不符合条件,前端展示报错信息 from django.shortcuts import render,HttpRes ...