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就有問題) 課設上的要求也沒全完成 

不過 美化就這樣了(比不上大佬的美化) 湊合看吧


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM