0
点赞
收藏
分享

微信扫一扫

QT开发(四)—— 项目实战:学生管理系统,QMessageBox,QTableView和QFile的使用

Hello,大家好,我们又开始来学习新的QT小项目了,这个项目就是学生管理系统,我也是在网易云的课堂上学习的哦,如果想看效果图的直接滑到文章的最下面即可

我们首先说一下,这个项目的组成是一个WindowView和两个Dialog,首先我们来看下主页的WindowView的UI效果

QT开发(四)—— 项目实战:学生管理系统,QMessageBox,QTableView和QFile的使用_ui

可以看到这里非常的简单,只是放了一个Label,主要的功能在于左上角的菜单栏,关于菜单栏如何创建,可以看下UI上

QT开发(四)—— 项目实战:学生管理系统,QMessageBox,QTableView和QFile的使用_qt_02

双击即可创建菜单栏了,至于他的信号怎么发送,需要点击下面的功能框

QT开发(四)—— 项目实战:学生管理系统,QMessageBox,QTableView和QFile的使用_qt_03

我们选中Action Editor,然后右键对应的对象即可,所以我们来看下主页的头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "addstuview.h"
#include "querystuview.h"
#include "aboutview.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void on_menu_add_stu_triggered();

void on_menu_query_stu_triggered();

void on_menu_about_triggered();

private:
Ui::MainWindow *ui;
AddStuView addView;
QueryStuView queryView;
AboutView aboutView;
};

#endif // MAINWINDOW_H

这里我只是定义了对应的添加和查询的两个功能View的对象以及三个菜单栏的槽函数

  • 查询学生
  • 添加学生
  • 关于

那么我们来看下我们的查询学生的View,我们先看头文件

#ifndef ADDSTUVIEW_H
#define ADDSTUVIEW_H

#include <QDialog>

namespace Ui {
class AddStuView;
}

class AddStuView : public QDialog
{
Q_OBJECT

public:
explicit AddStuView(QWidget *parent = 0);
~AddStuView();

public:
//初始化
void init();
//获取学员信息
void getStuViewData();
//打印信息
void print(const QString str);
//弹出提示
void showConfirmDialog(const QString str);
//检查数据合法
bool checkData(const QString name,const QString number);
//保存数据
void saveStuData();
//清空当前数据
void clearNowData();
//获取性别
QString getSex();
//获取爱好
QString getHobby();

private slots:
void on_btn_confirm_clicked();

void on_btn_cancel_clicked();

private:
Ui::AddStuView *ui;
bool isDebug = true;
QString content;
};

#endif // ADDSTUVIEW_H

头文件里,我定义了一堆的公开函数以及两个槽函数,分别是确定和取消,那么我们跟随他的构造函数一起来看看流程吧

我在构造函数中首先初始化了一些状态

void AddStuView::init()
{
//默认选中
this->ui->ck_boy->setChecked(true);
this->ui->cb_blue->setChecked(true);
}

对了,我们来看下UI吧

QT开发(四)—— 项目实战:学生管理系统,QMessageBox,QTableView和QFile的使用_ui_04

我们初始化的含义就是让性别和兴趣都有默认项

然后就要看下我们的确定按钮的槽函数了,因为一切的逻辑都是从这里开始的

//确定按钮
void AddStuView::on_btn_confirm_clicked()
{
this->getStuViewData();
}

为了代码的可读性我封装了一个函数getStuViewData来获取用户输入的相关信息

//获取添加学生的信息
void AddStuView::getStuViewData()
{
QString name = this->ui->et_name->text();
QString number = this->ui->et_number->text();
QString age = this->ui->cb_age->currentText();
QString school = this->ui->cb_school->currentText();

QString sex = this->getSex();
QString hobby = this->getHobby();

this -> content =
"姓名:" + name + "\n" +
"学号:" + number+ "\n" +
"性别:" + sex + "\n" +
"年龄:" + age + "\n" +
"学院:" + school + "\n" +
"爱好:" + hobby ;

this->print(this -> content);

//检测参数合法性
bool isCheck = this->checkData(name,number);

if(isCheck)
{
//弹框提示
this->showConfirmDialog(this -> content);
}
}

在这里我又创建了两个函数分别是getSex和getHobby来获取性别和兴趣,因为这些都是多选项所以不方便写一堆在一起

//获取性别
QString AddStuView::getSex()
{
QString sex = "男";
bool isCkBoy = this->ui->ck_boy->isChecked();
bool isCkGirl = this->ui->ck_girl->isChecked();

if(isCkBoy)
{
sex = "男";
}

if(isCkGirl)
{
sex = "女";
}
return sex;
}

//获取爱好
QString AddStuView::getHobby()
{
QList<QString> list;
if(this->ui->cb_blue->isChecked())
{
list.append("篮球");
}
if(this->ui->cb_voll->isChecked())
{
list.append("排球");
}
if(this->ui->cb_foot->isChecked())
{
list.append("足球");
}
if(this->ui->cb_bod->isChecked())
{
list.append("羽毛球");
}

QString hobby;
for (int i = 0; i < list.length(); ++i) {
hobby.append(list[i]);
if(i != (list.length()-1)){
hobby.append( ",");
}
}
return hobby;
}

当我们获取到相关的信息并且拼接在content变量中的时候我这里检测了一下参数的合法性,预防用户不输入导致我们程序的异常

//检查数据合法
bool AddStuView::checkData(const QString name, const QString number)
{
if(name.length() == 0)
{
//错误提示
QMessageBox::critical(this,"错误","输入框不能为空","确定");
return false;
}
if(number.length() == 0)
{
//错误提示
QMessageBox::critical(this,"错误","输入框不能为空","确定");
return false;
}
if(number.length() < 10)
{
//错误提示
QMessageBox::critical(this,"错误","学号必须大于等于十位","确定");
return false;
}
return true;
}

这里会弹出QMessageBox的提示框,这是他自带的简洁实现方法,我们在下面还有具体的实现方法,检测完合法性,我们就弹出窗口让用户去确定信息了

//显示Dialog
void AddStuView::showConfirmDialog(const QString str)
{
QMessageBox box;
box.setWindowTitle("请确定信息");
box.setText(str);
QPushButton* btnConfirm = box.addButton("确定",QMessageBox::AcceptRole);
QPushButton* btnCancel = box.addButton("取消",QMessageBox::RejectRole);
box.setDefaultButton(btnConfirm);
int ret = box.exec();

switch(ret)
{
case QMessageBox::AcceptRole:
//保存数据
this->saveStuData();
//清空当前数据
this->clearNowData();
break;
case QMessageBox::RejectRole:
box.close();
break;
}

}

这里对应的UI是这个效果

QT开发(四)—— 项目实战:学生管理系统,QMessageBox,QTableView和QFile的使用_管理_05

如果用户点击了确定也就触发了我们的槽,我们在这里做了两件事情

  • 保存数据
  • 清空UI数据

先看清空UI数据,实际上就是还原一下用户的输入,让用户可以继续录入学生信息

//清除当前数据
void AddStuView::clearNowData()
{
this->ui->et_name->setText("");
this->ui->et_number->setText("");
this->ui->ck_boy->setChecked(true);
this->ui->cb_age->setCurrentIndex(0);
this->ui->cb_school->setCurrentIndex(0);

this->ui->cb_blue->setChecked(true);
this->ui->cb_voll->setChecked(false);
this->ui->cb_foot->setChecked(false);
this->ui->cb_bod->setChecked(false);

//获取焦点
this->ui->et_name->setFocus();
}

紧接着,我们要保存数据,用到的是QFile

//保存数据
void AddStuView::saveStuData()
{
QFile file("stu.txt");

if (!file.open(QIODevice::Append | QIODevice::Text))
{
QMessageBox::critical(this,"错误","无法保存文件","确定");
return;
}

QTextStream out(&file);

//重新拼接数据,便于存储
QString cnt = this->content
.replace("\n"," ")
.remove("姓名:")
.remove("学号:")
.remove("性别:")
.remove("年龄:")
.remove("学院:")
.remove("爱好:");

this->print(cnt);

//写入
out << cnt + "\n";
}

这里我们保存数据做了很多的处理

  • 首先是判断下文件是否可以操作
  • 紧接着对content进行过滤去除换行和标题
  • 然后写入

写入之后可以在我们的build工程目录里看下相关信息

QT开发(四)—— 项目实战:学生管理系统,QMessageBox,QTableView和QFile的使用_管理_06

到这里我们的全部添加数据算是写完了,来看下完整代码

#include "addstuview.h"
#include "ui_addstuview.h"
#include <QString>
#include <QDebug>
#include <QMessageBox>
#include <QPushButton>
#include <QFile>
#include <QTextStream>
#include <QIODevice>

AddStuView::AddStuView(QWidget *parent) :
QDialog(parent),
ui(new Ui::AddStuView)
{
ui->setupUi(this);
this->init();
}

AddStuView::~AddStuView()
{
delete ui;
}

void AddStuView::init()
{
//默认选中
this->ui->ck_boy->setChecked(true);
this->ui->cb_blue->setChecked(true);
}

//确定按钮
void AddStuView::on_btn_confirm_clicked()
{
this->getStuViewData();
}
//取消按钮
void AddStuView::on_btn_cancel_clicked()
{
this->close();
}

//获取添加学生的信息
void AddStuView::getStuViewData()
{
QString name = this->ui->et_name->text();
QString number = this->ui->et_number->text();
QString age = this->ui->cb_age->currentText();
QString school = this->ui->cb_school->currentText();

QString sex = this->getSex();
QString hobby = this->getHobby();

this -> content =
"姓名:" + name + "\n" +
"学号:" + number+ "\n" +
"性别:" + sex + "\n" +
"年龄:" + age + "\n" +
"学院:" + school + "\n" +
"爱好:" + hobby ;

this->print(this -> content);

//检测参数合法性
bool isCheck = this->checkData(name,number);

if(isCheck)
{
//弹框提示
this->showConfirmDialog(this -> content);
}
}

//打印
void AddStuView::print(const QString str)
{
if(this->isDebug)
{
qDebug() << str;
}
}

//显示Dialog
void AddStuView::showConfirmDialog(const QString str)
{
QMessageBox box;
box.setWindowTitle("请确定信息");
box.setText(str);
QPushButton* btnConfirm = box.addButton("确定",QMessageBox::AcceptRole);
QPushButton* btnCancel = box.addButton("取消",QMessageBox::RejectRole);
box.setDefaultButton(btnConfirm);
int ret = box.exec();

switch(ret)
{
case QMessageBox::AcceptRole:
//保存数据
this->saveStuData();
//清空当前数据
this->clearNowData();
break;
case QMessageBox::RejectRole:
box.close();
break;
}

}

//检查数据合法
bool AddStuView::checkData(const QString name, const QString number)
{
if(name.length() == 0)
{
//错误提示
QMessageBox::critical(this,"错误","输入框不能为空","确定");
return false;
}
if(number.length() == 0)
{
//错误提示
QMessageBox::critical(this,"错误","输入框不能为空","确定");
return false;
}
if(number.length() < 10)
{
//错误提示
QMessageBox::critical(this,"错误","学号必须大于等于十位","确定");
return false;
}
return true;
}

//保存数据
void AddStuView::saveStuData()
{
QFile file("stu.txt");

if (!file.open(QIODevice::Append | QIODevice::Text))
{
QMessageBox::critical(this,"错误","无法保存文件","确定");
return;
}

QTextStream out(&file);

//重新拼接数据,便于存储
QString cnt = this->content
.replace("\n"," ")
.remove("姓名:")
.remove("学号:")
.remove("性别:")
.remove("年龄:")
.remove("学院:")
.remove("爱好:");

this->print(cnt);

//写入
out << cnt + "\n";
}

//清除当前数据
void AddStuView::clearNowData()
{
this->ui->et_name->setText("");
this->ui->et_number->setText("");
this->ui->ck_boy->setChecked(true);
this->ui->cb_age->setCurrentIndex(0);
this->ui->cb_school->setCurrentIndex(0);

this->ui->cb_blue->setChecked(true);
this->ui->cb_voll->setChecked(false);
this->ui->cb_foot->setChecked(false);
this->ui->cb_bod->setChecked(false);

//获取焦点
this->ui->et_name->setFocus();
}

//获取性别
QString AddStuView::getSex()
{
QString sex = "男";
bool isCkBoy = this->ui->ck_boy->isChecked();
bool isCkGirl = this->ui->ck_girl->isChecked();

if(isCkBoy)
{
sex = "男";
}

if(isCkGirl)
{
sex = "女";
}
return sex;
}

//获取爱好
QString AddStuView::getHobby()
{
QList<QString> list;
if(this->ui->cb_blue->isChecked())
{
list.append("篮球");
}
if(this->ui->cb_voll->isChecked())
{
list.append("排球");
}
if(this->ui->cb_foot->isChecked())
{
list.append("足球");
}
if(this->ui->cb_bod->isChecked())
{
list.append("羽毛球");
}

QString hobby;
for (int i = 0; i < list.length(); ++i) {
hobby.append(list[i]);
if(i != (list.length()-1)){
hobby.append( ",");
}
}
return hobby;
}

我们现在开始看下查询的代码,现在看下头文件

#ifndef QUERYSTUVIEW_H
#define QUERYSTUVIEW_H

#include <QDialog>
#include <QString>
#include <QList>
#include <QStandardItem>
#include <QStandardItemModel>
#include <QStringList>

namespace Ui {
class QueryStuView;
}

class QueryStuView : public QDialog
{
Q_OBJECT

public:
explicit QueryStuView(QWidget *parent = 0);
~QueryStuView();

private:
//初始化
void init();
//获取输入框数据
bool getQueryText();
//获取文件数据
void getFileData();
//解析文件数据
void parsingFileData();
//显示UI
void showUI(int row,QStringList list);

private slots:
void on_btn_query_stu_clicked();

private:
Ui::QueryStuView *ui;
QString queryText;
int index = 0;
QList<QString> list_line;
QStandardItemModel* model;

};

#endif // QUERYSTUVIEW_H

头文件里,我们注意到有一个对象QStandardItemModel,这个就是实现QTableView的重要部分了,我们先看下UI

QT开发(四)—— 项目实战:学生管理系统,QMessageBox,QTableView和QFile的使用_网易_07

那么我们怎么实现呢?还是按照逻辑去跟代码

void QueryStuView::init()
{
//实例化
this->model = new QStandardItemModel;

//设置表头
this->model->setHorizontalHeaderItem(0,new QStandardItem("姓名"));
this->model->setHorizontalHeaderItem(1,new QStandardItem("学号"));
this->model->setHorizontalHeaderItem(2,new QStandardItem("性别"));
this->model->setHorizontalHeaderItem(3,new QStandardItem("年龄"));
this->model->setHorizontalHeaderItem(4,new QStandardItem("院系"));
this->model->setHorizontalHeaderItem(5,new QStandardItem("爱好"));

//设置视图
this->ui->tab_stu_view->setModel(model);

//设置列宽
this->ui->tab_stu_view->setColumnWidth(1,500);
}

可以看到,我们初始化的时候,就把QStandardItemModel的对象new出来了,然后设置了一下头部的标题

然后要看触发的槽,也就是搜索按钮了

//点击搜索
void QueryStuView::on_btn_query_stu_clicked()
{
qDebug() << "点击搜索";
this->index = this->ui->cb_conditions->currentIndex();
bool isHave = this->getQueryText();

if(isHave)
{
//开始查询文件
this->getFileData();
}
}

我们点击搜索后,获取了当前的筛选条件以及输入框内的文字

//获取输入框数据
bool QueryStuView::getQueryText()
{
//获取输入框
this-> queryText = this->ui->et_query->text();
if(this->queryText.length() == 0)
{
QMessageBox::critical(this,"错误","输入框不能为空","确定");
return false;
}
return true;

}

如果你输入有内容,我们就开始查询下我们的文件

//获取文件数据
void QueryStuView::getFileData()
{
qDebug() << "获取文件";

//清理数据
this->list_line.clear();
this->model->clear();

QFile file("stu.txt");
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QMessageBox::critical(this,"错误","无法打开文件","确定");
return;
}
QTextStream in(&file);

while (!in.atEnd()) {
QString line = in.readLine();
this->list_line.append(line);
}
file.close();

//解析文件数据
this->parsingFileData();
}

这里我们获取到文件数据list_line后开始去解析

//解析文件数据
void QueryStuView::parsingFileData()
{
qDebug() << "解析文件";
int row = 0;
//遍历数据
for (int i = 0; i < this->list_line.length(); ++i) {
QString str = this->list_line.at(i);
//分割
QStringList list = (str.split(" "));
qDebug() << index;
//按照条件
switch(this->index)
{
//姓名
case 0:
if(this->queryText == list.at(0)){
this->showUI(row++,list);
}
break;
//学号
case 1:
if(this->queryText == list.at(1)){
this->showUI(row++,list);
}
break;
//院系
case 2:
if(this->queryText == list.at(4)){
this->showUI(row++,list);
}
break;
}

}

}

遍历后根据筛选条件来显示具体的数据

//显示UI
void QueryStuView::showUI(int row,QStringList list)
{
qDebug() << "显示UI:" << list.length();
for (int i = 0; i < list.length(); ++i) {
this->model ->setItem(row,i,new QStandardItem(list.at(i)));
}
}

嗯 ,到这里也就完成了我们的查询功能了,来看下完整的代码

#include "querystuview.h"
#include "ui_querystuview.h"
#include <QMessageBox>
#include <QFile>
#include <QIODevice>
#include <QTextStream>
#include <QDebug>

QueryStuView::QueryStuView(QWidget *parent) :
QDialog(parent),
ui(new Ui::QueryStuView)
{
ui->setupUi(this);

this->init();
}

QueryStuView::~QueryStuView()
{
delete ui;
}

void QueryStuView::init()
{
//实例化
this->model = new QStandardItemModel;

//设置表头
this->model->setHorizontalHeaderItem(0,new QStandardItem("姓名"));
this->model->setHorizontalHeaderItem(1,new QStandardItem("学号"));
this->model->setHorizontalHeaderItem(2,new QStandardItem("性别"));
this->model->setHorizontalHeaderItem(3,new QStandardItem("年龄"));
this->model->setHorizontalHeaderItem(4,new QStandardItem("院系"));
this->model->setHorizontalHeaderItem(5,new QStandardItem("爱好"));

//设置视图
this->ui->tab_stu_view->setModel(model);

//设置列宽
this->ui->tab_stu_view->setColumnWidth(1,500);
}

//点击搜索
void QueryStuView::on_btn_query_stu_clicked()
{
qDebug() << "点击搜索";
this->index = this->ui->cb_conditions->currentIndex();
bool isHave = this->getQueryText();

if(isHave)
{
//开始查询文件
this->getFileData();
}
}

//获取输入框数据
bool QueryStuView::getQueryText()
{
//获取输入框
this-> queryText = this->ui->et_query->text();
if(this->queryText.length() == 0)
{
QMessageBox::critical(this,"错误","输入框不能为空","确定");
return false;
}
return true;

}
//获取文件数据
void QueryStuView::getFileData()
{
qDebug() << "获取文件";

//清理数据
this->list_line.clear();
this->model->clear();

QFile file("stu.txt");
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QMessageBox::critical(this,"错误","无法打开文件","确定");
return;
}
QTextStream in(&file);

while (!in.atEnd()) {
QString line = in.readLine();
this->list_line.append(line);
}
file.close();

//解析文件数据
this->parsingFileData();
}

//解析文件数据
void QueryStuView::parsingFileData()
{
qDebug() << "解析文件";
int row = 0;
//遍历数据
for (int i = 0; i < this->list_line.length(); ++i) {
QString str = this->list_line.at(i);
//分割
QStringList list = (str.split(" "));
qDebug() << index;
//按照条件
switch(this->index)
{
//姓名
case 0:
if(this->queryText == list.at(0)){
this->showUI(row++,list);
}
break;
//学号
case 1:
if(this->queryText == list.at(1)){
this->showUI(row++,list);
}
break;
//院系
case 2:
if(this->queryText == list.at(4)){
this->showUI(row++,list);
}
break;
}

}

}

//显示UI
void QueryStuView::showUI(int row,QStringList list)
{
qDebug() << "显示UI:" << list.length();
for (int i = 0; i < list.length(); ++i) {
this->model ->setItem(row,i,new QStandardItem(list.at(i)));
}
}

好,最后一个关于,其实就是个UI

QT开发(四)—— 项目实战:学生管理系统,QMessageBox,QTableView和QFile的使用_标签_08

有兴趣的可以关注下我的公众号和加群,我就不过多打广告了

来看下实际的效果吧

QT开发(四)—— 项目实战:学生管理系统,QMessageBox,QTableView和QFile的使用_管理_09

源码下载:

举报

相关推荐

0 条评论