整个系统界面如下图:(源码在最后面)
1、点击“选择目的文件”即可通过文件路径选择进行查询的文件(XML)
2、选择文件过后主窗口中的table显示学生信息列表
3、点击“增加学生”、“查询学生”、“修改信息”、“删除学生”依次出现下面各图:
具体实现图就不再贴了,所有对学生信息的操作结果都展示在主窗口中的table中。
“刷新table”可将当前学生列表刷新,主要用于查询过后的table恢复。
点击“保存”即可将操作结果保存至原文件中。
接下来直接贴代码:
StudentMgrUI.h----------------主窗口
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_StudentMgrUI.h"
#include "studentMgr.h"
#include <QByteArray>
#include <QFileDialog>
class StudentMgrUI : public QMainWindow
{
Q_OBJECT
public:
StudentMgrUI(QWidget *parent = Q_NULLPTR);
public slots:
///<summary>
///进入增加学生信息界面
///</summary>
void addRecordslot();
///<summary>
///进入查询学生信息界面
///</summary>
void queryRecordslot();
///<summary>
///进入修改学生信息界面
///</summary>
void modifyRecordslot();
///<summary>
///进入删除学生信息界面
///</summary>
void delRecordslot();
///<summary>
///进入选择文件路径界面
///</summary>
void choiceFileslot();
///<summary>
///刷新学生信息主界面
///</summary>
void refreshslot();
///<summary>
///保存操作
///</summary>
void saveslot();
public:
Ui::StudentMgrUIClass ui;
};
StudentMgrUI.cpp----------------主窗口
#include "StudentMgrUI.h"
#include "queryRecordDlg.h"
#include "addRecordDlg.h"
#include "delRecordDlg.h"
#include "modifyRecordDlg.h"
#include "choiceFileDlg.h"
#include <QMessageBox>
///全局变量提供数据写入写出
StudentMgr studentInformationMain;
///不合理输入循环控制
int loopControl=0;
StudentMgrUI::StudentMgrUI(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
}
void StudentMgrUI::addRecordslot ()
{
addRecordDlg dlg;
int res = dlg.exec();
if(res == QDialog::Accepted&&loopControl==0)
{
///增加学生的信息
Student temp;
temp._id = dlg.ui.idLineEdit->text().toLocal8Bit();
temp._name = dlg.ui.nameLineEdit->text().toLocal8Bit();
temp._sex = dlg.ui.sexLineEdit->text().toLocal8Bit();
temp._telnumber = dlg.ui.telLineEdit->text().toLocal8Bit();
///增加学生
studentInformationMain.addStudent (temp);
///刷新table
refreshslot();
loopControl=0;
}
}
void StudentMgrUI::queryRecordslot ()
{
queryRecordDlg dlg;
int res = dlg.exec();
if(res == QDialog::Accepted&&loopControl==0)
{
const Student* queryResult;
///查询学生学号
std::string str;
const char* queryId = str.data ();
str = dlg.ui.lineEditQuery->text ().toLocal8Bit ();
///查询学生的信息
queryResult = studentInformationMain.query (queryId);
QString id = QString::fromLocal8Bit(queryResult->_id.c_str());
QString name = QString::fromLocal8Bit(queryResult->_name.c_str());
QString sex = QString::fromLocal8Bit(queryResult->_sex.c_str());
QString tel = QString::fromLocal8Bit(queryResult->_telnumber.c_str());
///如果查找到对应学生信息则更新至table
if(queryResult->_id!="")
{
ui.studentInformation->setRowCount(0);
int rowCont;
rowCont=ui.studentInformation->rowCount();
ui.studentInformation->insertRow(rowCont);
ui.studentInformation->setItem(rowCont,0,new QTableWidgetItem(id));
ui.studentInformation->setItem(rowCont,1,new QTableWidgetItem(name));
ui.studentInformation->setItem(rowCont,2,new QTableWidgetItem(sex));
ui.studentInformation->setItem(rowCont,3,new QTableWidgetItem(tel));
}
loopControl=0;
}
}
void StudentMgrUI::modifyRecordslot ()
{
modifyRecordDlg dlg;
int res = dlg.exec();
if(res == QDialog::Accepted&&loopControl==0)
{
Student* queryResultC;
///更改学生学号
std::string str;
const char* id = str.data ();
str = dlg.ui.idLineEdit->text ().toLocal8Bit ();
///返回要更改学号学生的信息(此处不取学号,学号不允更改)
queryResultC = studentInformationMain.query (id);
///接收更改信息
queryResultC->_name = dlg.ui.nameLineEdit->text ().toLocal8Bit ();
queryResultC->_sex = dlg.ui.sexLineEdit->text ().toLocal8Bit ();
queryResultC->_telnumber = dlg.ui.telLineEdit->text ().toLocal8Bit ();
///更改信息
studentInformationMain.modifyStudent (*queryResultC);
///刷新table
refreshslot();
loopControl=0;
}
}
void StudentMgrUI::delRecordslot ()
{
delRecordDlg dlg;
int res = dlg.exec();
if(res == QDialog::Accepted&&loopControl==0)
{
std::string str;
const char* id = str.data ();
///删除学生的学号
str = dlg.ui.delLineEdit->text ().toLocal8Bit ();
///据学号删除学生信息
studentInformationMain.delStudent (id);
///刷新table
refreshslot();
loopControl=0;
}
}
void StudentMgrUI::choiceFileslot ()
{
///选择文件
QString filename;
QWidget *qwidget = new QWidget ();
filename = QFileDialog::getOpenFileName (qwidget, QString::fromLocal8Bit("选择文件"), "", nullptr);
QMessageBox::warning (NULL, QString::fromLocal8Bit("展示路径"), filename);
///文件名转换
std::string fileTemp;
const char* fileName;
fileTemp = filename.toLocal8Bit();
fileName = fileTemp.data();
///打开文件,传入全局变量
studentInformationMain.open(fileName);
///刷新table
refreshslot();
}
void StudentMgrUI::refreshslot ()
{
///清空table表
ui.studentInformation->setRowCount(0);
///全局变量传入table中
StudentMgr::MapStudent::iterator it;
for (it = studentInformationMain._students.begin();it != studentInformationMain._students.end();it++)
{
int rowCont;
rowCont = ui.studentInformation->rowCount ();
ui.studentInformation->insertRow (rowCont);
QString id = QString::fromLocal8Bit(it->second._id.c_str());
QString name = QString::fromLocal8Bit(it->second._name.c_str());
QString sex = QString::fromLocal8Bit(it->second._sex.c_str());
QString tel = QString::fromLocal8Bit(it->second._telnumber.c_str());
ui.studentInformation->setItem(rowCont,0,new QTableWidgetItem(id));
ui.studentInformation->setItem(rowCont,1,new QTableWidgetItem(name));
ui.studentInformation->setItem(rowCont,2,new QTableWidgetItem(sex));
ui.studentInformation->setItem(rowCont,3,new QTableWidgetItem(tel));
}
}
void StudentMgrUI::saveslot ()
{
///全局变量传入文件
studentInformationMain.save();
}
addRecordDlg.h-------------点击“增加学生”弹出的子窗口
#pragma once
#include <QDialog>
#include "ui_addRecordDlg.h"
class addRecordDlg : public QDialog
{
Q_OBJECT
public:
addRecordDlg(QWidget *parent = Q_NULLPTR);
~addRecordDlg();
public slots:
///<summary>
///增加学生信息界面
///</summary>
void addRecordslot();
public:
Ui::addRecordDlg ui;
};
相似的删改差和选择文件的.h就不贴了,同addRecordDlg.h。(下面的.cpp也如此)
addRecordDlg.cpp-------------点击“增加学生”弹出的子窗口
#include "addRecordDlg.h"
#include <QMessageBox>
#include "StudentMgrUI.h"
extern int loopControl;
addRecordDlg::addRecordDlg(QWidget *parent)
: QDialog(parent)
{
ui.setupUi(this);
}
addRecordDlg::~addRecordDlg()
{
}
void addRecordDlg::addRecordslot()
{
if(ui.idLineEdit->text().isEmpty())
{
QMessageBox::information(0,"tooltip",QString::fromLocal8Bit("学号不能为空"),0);
StudentMgrUI loop;
loop.addRecordslot();
loopControl++;
return;
}
if(ui.nameLineEdit->text().isEmpty())
{
QMessageBox::information(0,"tooltip",QString::fromLocal8Bit("姓名不能为空"),0);
StudentMgrUI loop;
loop.addRecordslot();
loopControl++;
return;
}
if(ui.sexLineEdit->text().isEmpty())
{
QMessageBox::information(0,"tooltip",QString::fromLocal8Bit("性别不能为空"),0);
StudentMgrUI loop;
loop.addRecordslot();
loopControl++;
return;
}
if(ui.telLineEdit->text().isEmpty())
{
QMessageBox::information(0,"tooltip",QString::fromLocal8Bit("电话不能为空"),0);
StudentMgrUI loop;
loop.addRecordslot();
loopControl++;
return;
}
accepted();
}
studentMgr.h--------------具体函数操作
#pragma once
#include <map>
#include <vector>
#include <string>
class Student
{
public:
std::string _name;
std::string _sex;
std::string _id;
std::string _telnumber;
};
class StudentMgr
{
public:
using MapStudent = std::map<std::string,Student>;
//protected:
public:
MapStudent _students;
//const char* _fileName;
char _fileName[128];
public:
///<summary>
///打开学生信息文件,并将信息传至容器中
///</summary>
///<param name="fileName">文件名称</param>
///<return>打开成功返回true,失败返回false</return>
bool open(const char* fileName);
///<summary>
///保存学生信息文件,将容器中信息传回文件
///</summary>
///<param name="fileName">文件名称</param>
///<return>保存成功返回true,失败返回false</return>
bool save();
///<summary>
///增加一条学生信息
///</summary>
///<param name="stu">Student类的对象,其中包含学生的学号等基本信息</param>
///<return>增加成功返回true,失败返回false</return>
bool addStudent(const Student& stu);
///<summary>
///删除该学号的学生信息
///</summary>
///<param name="id">学生学号</param>
///<return>读取成功返回true,失败返回false</return>
bool delStudent(const char* id);
///<summary>
///按学号查询学生信息(该信息不可修改)
///</summary>
///<param name="id">学生学号</param>
///<return>查询成功返回true,失败返回失败提示</return>
const Student* query(const char* id) const ;
///<summary>
///按学号查询学生信息(该信息可修改)
///</summary>
///<param name="id">学生学号</param>
///<return>查询成功返回true,失败返回失败提示</return>
Student* query(const char* id);
///<summary>
///更改学生信息(该信息不可修改)
///</summary>
///<param name="stu">Student类的对象,其中包含学生的学号等基本信息</param>
///<return>更改成功返回true,失败返回失败提示</return>
bool modifyStudent(Student & stu);
};
#pragma once
studentMgr.cpp--------------具体函数操作
#include "StudentMgr.h"
#include "rapidxml.hpp"
#include "rapidxml_iterators.hpp"
#include "rapidxml_print.hpp"
#include "rapidxml_utils.hpp"
#include <iostream>
#include <QMessageBox>
typedef rapidxml::xml_node<> myNode;
bool StudentMgr::open(const char* fileName)
{
if(fileName!=nullptr)
{
//this->_fileName = fileName;
strcpy(_fileName, fileName);
///创建文件操作对象及解析
rapidxml::file<> fdoc(fileName);
rapidxml::xml_document<> doc;
doc.parse<0>(fdoc.data());
///节点信息
myNode* StudentInformation = doc.first_node();
std::cout<<StudentInformation->name()<<std::endl;
myNode* StudentList = StudentInformation->first_node();
std::cout<<StudentList->name()<<std::endl;
///遍历学生列表
if(StudentList!=nullptr)
for (myNode* Node = StudentList->first_node (); Node != nullptr; Node = Node->next_sibling ())
{
char name[255]={};
char sex[255]={};
char id[255]={};
char telnumber[255]={};
char* str2 = Node->value();
///map容器赋值
sscanf_s(str2,"%s %s %s %s",name,255,sex,255,id,255,telnumber,255);
Student studend1;
studend1._name = name;
studend1._sex = sex;
studend1._id = id;
studend1._telnumber = telnumber;
_students.insert(MapStudent::value_type(id,studend1));
///std::cout<<_Node->value()<<std::endl;
}
return true;
}
return false;
}
bool StudentMgr::save ()
{
///创建文件操作对象
rapidxml::xml_document<> doc;
myNode* root = doc.allocate_node(rapidxml::node_pi,doc.allocate_string("xml version='1.0' encoding='gb2312'"));
doc.append_node(root);
myNode* StudentInformation = doc.allocate_node(rapidxml::node_element,"StudentInformation",nullptr);
myNode* StudentList = doc.allocate_node(rapidxml::node_element,"StudentList",nullptr);
doc.append_node(StudentInformation);
StudentInformation->append_node(StudentList);
MapStudent::iterator it;
char str[1024];
const char* name;
const char* sex;
const char* id;
const char* telnumber;
int iter=0;
///取出容器内容
for (it = _students.begin (); it != _students.end (); it++)
{
name = it->second._name.data();
sex = it->second._sex.data();
id = it->second._id.data();
telnumber = it->second._telnumber.data();
sprintf_s(str,"%s %s %s %s",name,sex,id,telnumber);
StudentList->append_node(doc.allocate_node(rapidxml::node_element, "Student", doc.allocate_string(str, 1024)));
}
///打开文件并写入xml信息
std::string text;
rapidxml::print(back_inserter(text), doc, 0);
std::ofstream out(_fileName);
out<<doc;
return true;
}
bool StudentMgr::addStudent(const Student& stu)
{
Student studend1;
studend1._name = stu._name;
studend1._sex = stu._sex;
studend1._id = stu._id;
studend1._telnumber = stu._telnumber;
_students.insert(MapStudent::value_type(stu._id,studend1));
return true;
}
bool StudentMgr::delStudent(const char* id)
{
MapStudent::iterator it;
int size=_students.size();
for (it = _students.begin (); it != _students.end ();)
{
if (it->second._id == id)
{
it=_students.erase(it);
break;
}
else
{
it++;
}
}
if(size==_students.size())
QMessageBox::information(0,"tooltip",QString::fromLocal8Bit("没有该学号学生信息,删除失败"),0);
return true;
}
const Student* StudentMgr::query(const char* id) const
{
///创建文件操作对象及解析
static Student queryStudent={};
rapidxml::file<> fdoc(this->_fileName);
rapidxml::xml_document<> doc;
doc.parse<0>(fdoc.data());
///遍历节点信息
myNode* StudentInformation = doc.first_node();
myNode* StudentList = StudentInformation->first_node();
int judge = 0;
///遍历学生列表
if(StudentList!=nullptr)
for (myNode* Node = StudentList->first_node (); Node != nullptr; Node = Node->next_sibling ())
{
std::string sname;
std::string ssex;
std::string sid;
std::string stelnumber;
char* name = nullptr;
char* sex = nullptr;
char* idt = nullptr;
char* telnumber = nullptr;
char* str2 = Node->value();
///取出name
sscanf_s(str2,"%s %s %s %s",name,255,sex,255,idt,255,telnumber,255);
sname=name;
ssex=sex;
sid=idt;
stelnumber=telnumber;
///查找name匹配行信息
if(sid==id)
{
queryStudent._id = sid;
queryStudent._name = sname;
queryStudent._sex = ssex;
queryStudent._telnumber = stelnumber;
judge++;
}
}
if(judge==0)
{
QMessageBox::information(0,"tooltip",QString::fromLocal8Bit("没有该学号学生信息"),0);
}
return &queryStudent;
}
Student* StudentMgr::query(const char* id)
{
static Student queryStudent={};
MapStudent::iterator it;
int judge = 0;
for (it = _students.begin();it != _students.end();it++)
{
if(it->second._id==id)
{
queryStudent._id = it->second._id;
queryStudent._name = it->second._name;
queryStudent._sex = it->second._sex;
queryStudent._telnumber = it->second._telnumber;
judge++;
break;
}
}
if(judge==0)
{
QMessageBox::information (0, "tooltip", QString::fromLocal8Bit ("未查找到该学号学生"), 0);
}
return &queryStudent;
}
bool StudentMgr::modifyStudent (Student & stu)
{
std::string newname = stu._name;
std::string newsex = stu._sex;
std::string newid = stu._id;
std::string newtelnumber = stu._telnumber;
MapStudent::iterator it;
for (it = _students.begin();it!=_students.end();it++)
{
if(it->second._id==newid)
{
it->second._name = newname;
it->second._sex = newsex;
it->second._telnumber = newtelnumber;
break;
}
if(it==_students.end())
QMessageBox::information(0,"tooltip",QString::fromLocal8Bit("没有该学号学生信息"),0);
}
return false;
}
当然,每个窗口对应有.ui这里就不作描述。整个系统做下来差不多就这些,其中关键都在代码和注释中。
源码:链接: https://pan.baidu.com/s/1EJGmWNFbR30wmRKjedPHjw 提取码: qy1d