题目要求如下:
分析设计任务可以知道, 每个学生要包括复数个课程信息,同时复数个学生组成学生表 进行统一管理。
根据题目要求,程序要完成以下功能:
完成课程类、课程队列类、学生类、学生队列类四个类的创建:课程表类中为课程类的列表类,学生类的成员包括课程表类,学生表类为学生类的列表,数据结构如下图:
界面设计,尽量简洁美观:
通过对界面进行不同层次的布局操作让界面控件大小可以随窗口大小改变而改变,同时添加对话框中有label控件提醒,避免空文本的出现;
四个类与界面进行对接,通过界面可对创建类进行操作:
调用四个类中的成员函数,获取或修改类信息,同时用m_View_kind记录目前视图类型:0显示学生信息,1显示选课信息,2显示从0表查询,3显示从1表中查询,4显示特定课程的选课学生,在不同视图下可以进行相应的操作,而不能进行的操作,程序会进行提醒,避免bug的出现;
不同视图的显示要及时对视图种类和选中列表的索引进行刷新:
学生信息视图作为最底层视图,在这层视图时所用选中索引要进行刷新,学生信息视图作为主视图,课程信息视图作为副主视图,索引的刷新在这两个视图中进行,结构如下图;
在查询时要将查询结果的索引及时储存:
方便直接对查询结果进行操作,并注意推出查询要及时刷新,其中学生信息查询结果中的索引放入indexlist中,课程信息查询结果中的索引放入indexlist1中,可直接在查询结果视图中对成员对象进行操作;
特定课程进行学生信息显示:
通过对所有学生进行遍历操作进行查找,将结果索引进行储存显示,成绩排序运用QList中的qSort()函数直接对结构体中的某个属性进行排序;
在操作失误时会有提醒对话框:
创建一个提醒对话框,在进行可能会导致程序崩溃的操作时弹出制止;
文件:course.h\ .cpp//课程类:
c_ID//课程编号;c_Name//课程名称;credit//学分;term//学期;c_room//教室;grade//成绩
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class Course
{
public:
Course();
virtual ~Course();
Course& operator= (const Course & course);
void SaveCourse(QTextStream &aStream); //往流文件中写入成绩
void ReadCourse(QTextStream &aStream); //从流文件中读成绩
QString c_ID; //课程编号
QString c_Name; //课程名称
float credit; //学分
QString term; //学期
QString c_room; //教室
float grade; //成绩
};
#include "course.h"
Course::Course()
{
c_ID="";
c_Name="";
credit=0;
term="";
c_room="";
grade=0;
}
Course::~Course()
{
}
Course& Course::operator=(const Course &course)
{
c_ID=course.c_ID;
c_Name=course.c_Name;
credit=course.credit;
term=course.term;
c_room=course.c_room;
grade=course.grade;
return *this;
}
void Course::SaveCourse(QTextStream &aStream)
{
aStream<<c_ID<<"\t"<<c_Name<<"\t"<<credit<<"\t"<<term<<"\t"<<c_room<<"\t"<<grade<<"\n";
}
void Course::ReadCourse(QTextStream &aStream)
{
aStream>>c_ID;
aStream>>c_Name;
aStream>>credit;
aStream>>term;
aStream>>c_room;
aStream>>grade;
}
这里课程表和后面的学生表用QT5中的Qlist< Data >数据类型;
文件:courseinfotable.h\ .cpp//课程队列类:
m_course//课程类列表Qlist
#include"course.h"
class CourseInfoTable
{
public:
CourseInfoTable();
CourseInfoTable& operator= (const CourseInfoTable & course);
void SaveCourseInfoTable(QTextStream &aStream); //往流文件中写入成绩
void ReadCourseInfoTable(QTextStream &aStream);
void AddCourse(Course& course); //添加课程到课程表中
void DelCourse(int index); //根据列表索引删除课程
Course& GetCourse(int index); //根据列表索引得到课程
int CourseNum(); //得到课表课程数量
QList<Course> m_course; //课程列表
int c_num; //课程数量
};
#include "courseinfotable.h"
CourseInfoTable::CourseInfoTable()
{
m_course={};
c_num=0;
}
CourseInfoTable& CourseInfoTable::operator=(const CourseInfoTable &course)
{
m_course=course.m_course;
c_num=course.c_num;
return *this;
}
int CourseInfoTable::CourseNum()
{
c_num=m_course.size();
return this->c_num;
}
void CourseInfoTable::SaveCourseInfoTable(QTextStream &aStream)
{
int num=CourseNum();
aStream<<num<<"\n";
for(int i=0;i<num;i++)
{
Course temp = m_course[i];
temp.SaveCourse(aStream);
}
}
void CourseInfoTable::ReadCourseInfoTable(QTextStream &aStream)
{
aStream>>c_num;
for(int i=0;i<c_num;i++)
{
Course temp;
temp.ReadCourse(aStream);
m_course.append(temp);
}
}
void CourseInfoTable::AddCourse(Course &course)
{
m_course.append(course);
}
void CourseInfoTable::DelCourse(int index)
{
m_course.removeAt(index);
c_num-=1;
}
Course& CourseInfoTable::GetCourse(int index)
{
return m_course[index];
}
文件:student.h\ .cpp//学生类:
s_ID//学号;s_Name//姓名;s_class//班级;ph_number//电话;birthday//生日;adress//地址;s_courses//课程队列类CourseInfoTable
class Student
{
public:
Student();
Student& operator= (const Student& man);
virtual ~Student();
void SaveStudent(QTextStream &aStream); //保存数据
void ReadStudent(QTextStream &aStream); //读取数据
bool is_courses(); //判断是否选课
QString s_ID; //学号
QString s_Name; //姓名
QString s_class; //班级
QString ph_number; //电话
QDate birthday; //生日
QString adress; //地址
CourseInfoTable s_courses; //课程队列类
};
#include "student.h"
Student::Student()
{
s_ID="";
s_Name="";
s_class="";
ph_number="";
birthday=QDate();
adress="";
s_courses=CourseInfoTable();
}
Student::~Student()
{
}
Student& Student::operator=(const Student &man)
{
s_ID=man.s_ID;
s_Name=man.s_Name;
s_class=man.s_class;
ph_number=man.ph_number;
birthday=man.birthday;
adress=man.adress;
s_courses=man.s_courses;
return *this;
}
void Student::SaveStudent(QTextStream &aStream)
{
aStream<<s_ID<<"\t";
aStream<<s_Name<<"\t";
aStream<<s_class<<"\n";
aStream<<ph_number<<"\n";
aStream<<birthday.year()<<"\t"<<birthday.month()<<"\t"<<birthday.day()<<"\n";
aStream<<adress<<"\n";
s_courses.CourseInfoTable::SaveCourseInfoTable(aStream);
}
void Student::ReadStudent(QTextStream &aStream)
{
int year,month,day;
aStream>>s_ID;
aStream>>s_Name;
aStream>>s_class;
aStream>>ph_number;
aStream>>year;
aStream>>month;
aStream>>day;
aStream>>adress;
birthday.setDate(year,month,day);
s_courses.ReadCourseInfoTable(aStream);
}
bool Student::is_courses()
{
return s_courses.CourseNum()==0;
}
文件:studentinfotable.h.cpp//学生队列类:
m_student//学生队列类QList
class StudentInfoTable
{
public:
StudentInfoTable();
StudentInfoTable& operator= (const StudentInfoTable & student);
void SaveStudentInfoTable(QTextStream &aStream); //往流文件中写入数据
void ReadCourseInfoTable(QTextStream &aStream); //从流文件中读取数据
void AddStudent(Student& student); //添加学生添加到学生表中
void DelStudent(int index); //根据列表索引删除学生
Student& GetStudent(int index); //根据列表索引得到学生
int StudentNum(); //得到学生数量
QList<Student> m_student; //学生表
int s_num; //学生数量
};
#include "studentinfotable.h"
StudentInfoTable::StudentInfoTable()
{
m_student=QList<Student>();
s_num=0;
}
StudentInfoTable& StudentInfoTable::operator=(const StudentInfoTable &student)
{
m_student=student.m_student;
s_num=student.s_num;
return *this;
}
void StudentInfoTable::SaveStudentInfoTable(QTextStream &aStream)
{
int num=StudentNum();
aStream<<num<<"\n";
for(int i=0;i<num;i++)
{
m_student[i].SaveStudent(aStream);
aStream<<"\n";
}
}
void StudentInfoTable::ReadCourseInfoTable(QTextStream &aStream)
{
aStream>>s_num;
for(int i=0;i<s_num;i++)
{
Student temp_s;
temp_s.ReadStudent(aStream);
m_student.append(temp_s);
}
}
void StudentInfoTable::AddStudent(Student &student)
{
m_student.append(student);
s_num+=1;
}
void StudentInfoTable::DelStudent(int index)
{
m_student.removeAt(index);
s_num-=1;
}
Student& StudentInfoTable::GetStudent(int index)
{
return m_student[index];
}
int StudentInfoTable::StudentNum()
{
s_num=m_student.size();
return s_num;
}
创建方法:
文件:inputdialog_s.h\ .cpp\ .ui//添加学生对话框类:
返回对话框中textEdit中的文本
比如我们选择textChange()函数,它就会出现在.h文件中,它表示当textEdit控件中文本发生变化时,该函数就会运行,其他槽函数可以自行查找官方文档。
inputdialog_s.h(在创建后有一部分已经存在了,这里就直接贴过来啦)
#include
#include
namespace Ui {
class InputDialog_s;
}
class InputDialog_s : public QDialog
{
Q_OBJECT
public:
explicit InputDialog_s(QWidget *parent = nullptr);
~InputDialog_s();
QString is_Error(); //
void Show_error(const QString&tempstr);
//得到文本编辑框中的文本内容,方便后面与主窗口对接
QString Get_ID();
QString Get_Name();
QString Get_Class();
QString Get_number();
QDate Get_bir();
QString Get_adress();
void Label_Show();
private slots:
void on_textEdit_selectionChanged();
void on_textEdit_6_selectionChanged();
void on_textEdit_2_selectionChanged();
void on_textEdit_3_selectionChanged();
void on_textEdit_4_selectionChanged();
void on_dateEdit_editingFinished();
void on_textEdit_textChanged();
void on_textEdit_2_textChanged();
void on_textEdit_3_textChanged();
void on_textEdit_4_textChanged();
void on_textEdit_6_textChanged();
private:
Ui::InputDialog_s *ui;
};
#include "inputdialog_s.h"
#include "ui_inputdialog_s.h"
InputDialog_s::InputDialog_s(QWidget *parent) :
QDialog(parent),
ui(new Ui::InputDialog_s)
{
ui->setupUi(this);
}
InputDialog_s::~InputDialog_s()
{
delete ui;
}
QString InputDialog_s::Get_ID()
{
return ui->textEdit->toPlainText();
}
QString InputDialog_s::Get_Name()
{
return ui->textEdit_2->toPlainText();
}
QString InputDialog_s::Get_Class()
{
return ui->textEdit_3->toPlainText();
}
QString InputDialog_s::Get_number()
{
return ui->textEdit_4->toPlainText();
}
QDate InputDialog_s::Get_bir()
{
return ui->dateEdit->date();
}
QString InputDialog_s::Get_adress()
{
return ui->textEdit_6->toPlainText();
}
QString InputDialog_s::is_Error()
{
QString error;
if(Get_ID().isEmpty())
{
error="学号";
return error;
}
else if(Get_Name().isEmpty())
{
error="姓名";
return error;
}
else if(Get_Class().isEmpty())
{
error="班级";
return error;
}
else if(Get_number().isEmpty())
{
error="电话";
return error;
}
else if(Get_adress().isEmpty())
{
error="地址";
return error;
}
else
{
error="OK";
return error;
}
}
void InputDialog_s::Show_error(const QString &tempstr)
{
ui->label_7->setText(tempstr);
ui->label_7->setAlignment(Qt::AlignRight);
}
void InputDialog_s::Label_Show()
{
QString error=is_Error();
if(error=="OK")Show_error("点击OK即可添加!");
else Show_error(QString("%1为空!请输入!!").arg(error));
}
void InputDialog_s::on_textEdit_selectionChanged()
{
Label_Show();
}
void InputDialog_s::on_textEdit_6_selectionChanged()
{
Label_Show();
}
void InputDialog_s::on_textEdit_2_selectionChanged()
{
Label_Show();
}
void InputDialog_s::on_textEdit_3_selectionChanged()
{
Label_Show();
}
void InputDialog_s::on_textEdit_4_selectionChanged()
{
Label_Show();
}
void InputDialog_s::on_dateEdit_editingFinished()
{
Label_Show();
}
void InputDialog_s::on_textEdit_textChanged()
{
Label_Show();
}
void InputDialog_s::on_textEdit_2_textChanged()
{
Label_Show();
}
void InputDialog_s::on_textEdit_3_textChanged()
{
Label_Show();
}
void InputDialog_s::on_textEdit_4_textChanged()
{
Label_Show();
}
void InputDialog_s::on_textEdit_6_textChanged()
{
Label_Show();
}
与添加学生信息相似
文件:inputdialog_c.h\ .cpp\ .ui//添加课程对话框类:
返回对话框中textEdit中的文本
inputdialog_c.h
#include
namespace Ui {
class InputDialog_c;
}
class InputDialog_c : public QDialog
{
Q_OBJECT
public:
explicit InputDialog_c(QWidget *parent = nullptr);
~InputDialog_c();
QString is_Error(); //错误类型
void Show_error(const QString&tempstr); //判断编辑框中内容是否为空
//得到文本编辑框中的文本内容,方便后面与主窗口对接
void Show_Label();
QString Get_ID();
QString Get_Name();
float Get_Credit();
QString Get_term();
QString Get_room();
float Get_grade();
private slots:
void on_textEdit_selectionChanged();
void on_textEdit_textChanged();
void on_textEdit_2_selectionChanged();
void on_textEdit_2_textChanged();
void on_textEdit_3_selectionChanged();
void on_textEdit_3_textChanged();
void on_textEdit_4_selectionChanged();
void on_textEdit_4_textChanged();
void on_textEdit_5_selectionChanged();
void on_textEdit_5_textChanged();
void on_textEdit_6_textChanged();
void on_textEdit_6_selectionChanged();
private:
Ui::InputDialog_c *ui;
};
#include "inputdialog_c.h"
#include "ui_inputdialog_c.h"
InputDialog_c::InputDialog_c(QWidget *parent) :
QDialog(parent),
ui(new Ui::InputDialog_c)
{
ui->setupUi(this);
}
InputDialog_c::~InputDialog_c()
{
delete ui;
}
QString InputDialog_c::Get_ID()
{
return ui->textEdit->toPlainText();
}
QString InputDialog_c::Get_Name()
{
return ui->textEdit_2->toPlainText();
}
float InputDialog_c::Get_Credit()
{
return ui->textEdit_3->toPlainText().toFloat();
}
QString InputDialog_c::Get_term()
{
return ui->textEdit_4->toPlainText();
}
QString InputDialog_c::Get_room()
{
return ui->textEdit_5->toPlainText();
}
float InputDialog_c::Get_grade()
{
return ui->textEdit_6->toPlainText().toFloat();
}
QString InputDialog_c::is_Error()
{
QString error;
if(Get_ID().isEmpty())
{
error="课程编号";
return error;
}
else if(Get_Name().isEmpty())
{
error="课程名称";
return error;
}
else if(ui->textEdit_3->toPlainText().isEmpty())
{
error="学分";
return error;
}
else if(Get_term().isEmpty())
{
error="学期";
return error;
}
else if(Get_room().isEmpty())
{
error="教室";
return error;
}
else if(ui->textEdit_6->toPlainText().isEmpty())
{
error="成绩";
return error;
}
else
{
error="OK";
return error;
}
}
void InputDialog_c::Show_error(const QString &tempstr)
{
ui->label_7->setText(tempstr);
ui->label_7->setAlignment(Qt::AlignRight);
}
void InputDialog_c::Show_Label()
{
QString error=is_Error();
if(error=="OK")Show_error("点击OK即可添加!");
else Show_error(QString("%1为空!请输入!!").arg(error));
}
void InputDialog_c::on_textEdit_selectionChanged()
{
Show_Label();
}
void InputDialog_c::on_textEdit_textChanged()
{
Show_Label();
}
void InputDialog_c::on_textEdit_2_selectionChanged()
{
Show_Label();
}
void InputDialog_c::on_textEdit_2_textChanged()
{
Show_Label();
}
void InputDialog_c::on_textEdit_3_selectionChanged()
{
Show_Label();
}
void InputDialog_c::on_textEdit_3_textChanged()
{
Show_Label();
}
void InputDialog_c::on_textEdit_4_selectionChanged()
{
Show_Label();
}
void InputDialog_c::on_textEdit_4_textChanged()
{
Show_Label();
}
void InputDialog_c::on_textEdit_5_selectionChanged()
{
Show_Label();
}
void InputDialog_c::on_textEdit_5_textChanged()
{
Show_Label();
}
void InputDialog_c::on_textEdit_6_textChanged()
{
Show_Label();
}
void InputDialog_c::on_textEdit_6_selectionChanged()
{
Show_Label();
}
注意:这里的查询对话框只是得到查询信息的关键词,真正的查询的运行是在主窗口(MainWindow)中。
文件:selectdialog.h\ .cpp\ .ui//学生查询对话框:
可通过学号、姓名、班级三个特征进行查询
#include
namespace Ui {
class SelectDialog;
}
class SelectDialog : public QDialog
{
Q_OBJECT
public:
explicit SelectDialog(QWidget *parent = nullptr);
~SelectDialog();
QString Get_Value();//得到特征字符串
int Get_Comboboxindex();//得到特征索引
QString Get_Comboboxtext();//得到特征文本
private slots:
void on_comboBox_currentIndexChanged(const QString &arg1);
private:
Ui::SelectDialog *ui;
int m_index; //组合框索引
};
#include "selectdialog.h"
#include "ui_selectdialog.h"
SelectDialog::SelectDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SelectDialog)
{
ui->setupUi(this);
m_index=0;
}
SelectDialog::~SelectDialog()
{
delete ui;
}
QString SelectDialog::Get_Value()
{
return ui->textEdit->toPlainText();
}
int SelectDialog::Get_Comboboxindex()
{
return m_index;
}
void SelectDialog::on_comboBox_currentIndexChanged(const QString &arg1)
{
if(arg1=="学号")
m_index=0;
else if(arg1=="姓名")
m_index=1;
else m_index=2;
}
QString SelectDialog::Get_Comboboxtext()
{
if(m_index==0)return QString("学号");
else if(m_index==1)return QString("姓名");
else return QString("班级");
}
与学生信息查询相似
文件:selectdialog1.h\ .cpp\ .ui//课程查询对话框:
可通过课程编号、课程名称两个特征进行查询
#include
namespace Ui {
class SelectDialog1;
}
class SelectDialog1 : public QDialog
{
Q_OBJECT
public:
explicit SelectDialog1(QWidget *parent = nullptr);
~SelectDialog1();
QString Get_Value();//得到特征字符串
int Get_Comboboxindex();//得到特征索引
QString Get_Comboboxtext();//得到特征文本
private slots:
void on_comboBox_currentIndexChanged(const QString &arg1);
private:
Ui::SelectDialog1 *ui;
int m_index; //组合框索引
};
#include "selectdialog1.h"
#include "ui_selectdialog1.h"
SelectDialog1::SelectDialog1(QWidget *parent) :
QDialog(parent),
ui(new Ui::SelectDialog1)
{
ui->setupUi(this);
m_index=0;
}
SelectDialog1::~SelectDialog1()
{
delete ui;
}
QString SelectDialog1::Get_Value()
{
return ui->textEdit->toPlainText();
}
int SelectDialog1::Get_Comboboxindex()
{
return m_index;
}
QString SelectDialog1::Get_Comboboxtext()
{
if(m_index==0)return QString("课程编号");
else return QString("课程名称");
}
void SelectDialog1::on_comboBox_currentIndexChanged(const QString &arg1)
{
if(arg1=="课程编号")
m_index=0;
else m_index=1;
}
文件:tipsdialog.h\ .cpp\ .ui//提醒对话框:
避免一些禁止操作,并提醒
#include
namespace Ui {
class TipsDialog;
}
class TipsDialog : public QDialog
{
Q_OBJECT
public:
explicit TipsDialog(QWidget *parent = nullptr);
~TipsDialog();
void Tips_Show(const QString&tempstr);
private:
Ui::TipsDialog *ui;
};
#include "tipsdialog.h"
#include "ui_tipsdialog.h"
TipsDialog::TipsDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::TipsDialog)
{
ui->setupUi(this);
setWindowTitle("提示");
}
TipsDialog::~TipsDialog()
{
delete ui;
}
void TipsDialog::Tips_Show(const QString &tempstr)
{
ui->label->setText(tempstr);
}
文件:mainwindow.h\ .cpp\ .ui//主窗口:
*ui//主窗口对象; *studentTableView//表格视图对象; m_students//学生队列类; m_View_kind//目前视图类型0显示学生信息,1显示选课信息,2显示从0表查询,3显示从1表中查询,4显示特定课程的选课学生; m_row//学生视图0选中索引; indexlist//记录学生信息0中查询结果索引,在查询视图可以进行删除、修改操作QList
#include
#include
#include"studentinfotable.h"
#include
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void Show_Label1(const QString&tempstr);//数量显示
void Show_Label2(const QString&tempstr);//进程提醒
void Show_Label(const QString&tempstr);//名单备注
void Show_StudentTable(); //显示学生信息(不可修改)0
void Show_Table_s_changed(); //显示可修改
void Show_CourseTable(); //显示选课信息(不可修改)1
void Show_Table_c_changed(); //显示可修改
void Show_SelectTable(); //显示查询结果(不可修改)2->0;3->1
void Show_Table_sc_changed(); //显示可修改
void Show_CtoSTable(); //显示特定课程的学生信息(不可修改)4
private slots:
void on_actionOpen_triggered(); //打开文件
void on_actionSave_triggered(); //保存数据
void on_actionLoading_triggered(); //读取数据
void on_actionSaveto_triggered(); //另存为
void on_actionAdd_s_triggered(); //添加学生
void on_actionShow_s_triggered(); //学生信息视图
void on_tableView_clicked(const QModelIndex &index); //获取鼠标选中表格的索引
void on_actionDel_s_triggered(); //删除特定学生
void on_actionAdd_c_triggered(); //为特定学生添加课程信息
void on_actionShow_c_triggered(); //课程信息显示
void on_actionDel_c_triggered(); //删除某个课程信息
void on_actionSelect_triggered(); //查询
void on_ShowInfotableView_changed(); //修改数据
void on_actionChange_triggered(); //修改
void on_actionChangedSave_triggered(); //保存修改(推出修改)
void on_actionCtoS_Show_triggered(); //显示特定课程的学生信息
void on_actionAscending_triggered(); //升序
void on_actionDescending_triggered(); //降序
void on_tableView_doubleClicked(const QModelIndex &index);
private:
Ui::MainWindow *ui; //界面
QStandardItemModel *studentTableView; //表格视图
StudentInfoTable m_students; //学生名单类
int m_View_kind; //目前表格显示状态,0显示学生信息,1显示选课信息,
//2显示从0表查询,3显示从1表中查询,4显示特定课程的选课学生
int m_row; //0表中选中的行数
QList<int> indexlist; //记录0中查询结果索引,在查询视图可以进行删除、修改操作
int m_row1; //1表中选中的行数
QList<int> indexlist1; //记录1中查询结果索引,在查询视图可以进行删除、修改操作
bool can_change; //是否进行修改
};
直接利用添加菜单栏功能,大体设计如下:
注意:在添加完菜单功能时,会自动生成该Action Editor,如下图:
右键选择转到槽后会在mainwindow.h中自动生成该对应的槽函数,如下图:
因为该cpp文件不少于1000行,这里就详细解释几个重要的操作,其他的可以举一反三。
#include"readonlydelegate.h"
#include"tipsdialog.h"
#include"inputdialog_c.h"
#include"selectdialog.h"
#include"selectdialog1.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//建立view模型
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);//单次选择
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);//选中一个item
studentTableView=new QStandardItemModel();
//关联
ui->tableView->setModel(studentTableView);
//信号与槽进行连接(后续可在tabelView中直接修改)
connect(ui->tableView->itemDelegate(),&QAbstractItemDelegate::closeEditor,this,&MainWindow::on_ShowInfotableView_changed);
//成员默认构造
m_View_kind=0;
m_row=-1;
indexlist=QList<int>();
m_row1=-1;
indexlist1=QList<int>();
can_change=false;
}
//打开一个文件
void MainWindow::on_actionOpen_triggered()
{
QString curPath = QDir::currentPath();
QString dlgTitle = "选择一个文件";
QString filter = "文本文件(*.txt);;所有文件(*.*)";
QString aFileName = QFileDialog::getOpenFileName(this, dlgTitle, curPath, filter);
if(aFileName.isEmpty())
{
Show_Label2("打开文件失败!");
return;
}
Show_Label2("正在打开文件。。。");
//创建成功,打开文件
QFile aFile(aFileName);
if(!aFile.exists()) //文件不存在
{
Show_Label2("打开文件失败!");
return;
}
if(!aFile.open(QIODevice::ReadOnly | QIODevice::Text)) //以文本方式打开
{
Show_Label2("打开文件失败!");
return;
}
m_students=StudentInfoTable();//清空
QTextStream aStream(&aFile); //用文本流读取文件
aStream.setCodec(QTextCodec::codecForName("system")); //显示汉字
m_students.ReadCourseInfoTable(aStream);
aFile.close();//关闭文件
Show_Label2("文件读取成功!");
Show_StudentTable();
}
//保存一个文件
void MainWindow::on_actionSaveto_triggered()
{
QString curPath = QDir::currentPath();
QString dlgTitle = "另存为一个文件";
QString filter = "文本文件(*.txt);;所有文件(*.*)";
QString aFileName = QFileDialog::getSaveFileName(this, dlgTitle, curPath, filter);
if(aFileName.isEmpty())
{
Show_Label2("保存文件失败!");
return;
}
QFile aFile(aFileName);
if(!aFile.open(QIODevice::WriteOnly| QIODevice::Text)) //保存为文本
{
Show_Label2("保存文件失败!");
return;
}
QTextStream aStream(&aFile);//用文本流保存文件
aStream.setCodec(QTextCodec::codecForName("system")); //显示汉字
m_students.SaveStudentInfoTable(aStream);
aFile.close();//关闭文件
Show_Label2("文件保存成功!");
}
QStandardItemModel *studentTableView; //表格视图
void MainWindow::Show_StudentTable()
{
//不能修改
ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
can_change=false;
//显示学生信息
m_View_kind=0;
//重置选择行
m_row=-1;
m_row1=-1;
Show_Label("学生信息视图");
studentTableView->clear();
studentTableView->setColumnCount(7); //7列
//表头
//学号、姓名、班级、电话、生日、地址、是否选课
QStringList templist;
templist<<"学号"<<"姓名"<<"班级"<<"电话"<<"生日"<<"地址"<<"是否选课";
studentTableView->setHorizontalHeaderLabels(templist);
int RowCnt=m_students.StudentNum();//行数(不含标题)
studentTableView->setRowCount(RowCnt);
//遍历插入数据
QStandardItem *aTempItem;//临时的item
QString tempstr;
for(int i=0;i<RowCnt;++i)
{
Student temp_s=m_students.GetStudent(i);
tempstr=temp_s.s_ID;
aTempItem=new QStandardItem(tempstr);
studentTableView->setItem(i,0,aTempItem);
tempstr=temp_s.s_Name;
aTempItem=new QStandardItem(tempstr);
studentTableView->setItem(i,1,aTempItem);
tempstr=temp_s.s_class;
aTempItem=new QStandardItem(tempstr);
studentTableView->setItem(i,2,aTempItem);
tempstr=temp_s.ph_number;
aTempItem=new QStandardItem(tempstr);
studentTableView->setItem(i,3,aTempItem);
tempstr=temp_s.birthday.toString("yyyy/MM/dd");
aTempItem=new QStandardItem(tempstr);
studentTableView->setItem(i,4,aTempItem);
tempstr=temp_s.adress;
aTempItem=new QStandardItem(tempstr);
studentTableView->setItem(i,5,aTempItem);
if(temp_s.is_courses())tempstr="否";
else tempstr="是";
aTempItem=new QStandardItem(tempstr);
studentTableView->setItem(i,6,aTempItem);
}
Show_Label1(QString("学生人数:%1人").arg(m_students.StudentNum()));
//设置内容为只读
//ReadOnlyDelegate* readOnlyDelegate = new ReadOnlyDelegate(this);
//ui->tableView->setItemDelegateForColumn(6, readOnlyDelegate);
}
//为tableView控件的槽函数,函数参数为鼠标选中的表格索引
void MainWindow::on_tableView_clicked(const QModelIndex &index)
{
if(m_View_kind==0)
{
m_row=index.row();
Show_Label2(QString("已选中学号为%1 姓名为%2的学生").arg(m_students.GetStudent(m_row).s_ID).arg(m_students.GetStudent(m_row).s_Name));
}
else if(m_View_kind==1)
{
m_row1=index.row();
Show_Label2(QString("已选中课程编号为%1 名称为%2的课程信息").arg(m_students.GetStudent(m_row).s_courses.GetCourse(m_row1).c_ID).arg(m_students.GetStudent(m_row).s_courses.GetCourse(m_row1).c_Name));
}
else if(m_View_kind==2)
{
if(indexlist.isEmpty())m_row=-1;
else
{
m_row=indexlist[index.row()];
Show_Label2(QString("已选中学号为%1 姓名为%2的学生").arg(m_students.GetStudent(m_row).s_ID).arg(m_students.GetStudent(m_row).s_Name));
}
}
else if(m_View_kind==3)
{
if(indexlist1.isEmpty())m_row1=-1;
else
{
m_row1=indexlist1[index.row()];
Show_Label2(QString("已选中课程编号为%1 名称为%2的课程信息").arg(m_students.GetStudent(m_row).s_courses.GetCourse(m_row1).c_ID).arg(m_students.GetStudent(m_row).s_courses.GetCourse(m_row1).c_Name));
}
}
}
void MainWindow::on_actionSelect_triggered()
{
Show_Label2("正在进行查询。。。");
//查询前清空索引列表
indexlist.clear();
indexlist1.clear();
//在学生信息视图下
if(m_View_kind==0 || m_View_kind==2)
{
SelectDialog sg1;
sg1.setWindowTitle("学生信息查询");
int ret=sg1.exec();
if(ret==QDialog::Accepted)
{
int index=sg1.Get_Comboboxindex();//查询特征索引0为学号,1为姓名,2为班级
QString tempstr=sg1.Get_Value(); //查询特征值
//遍历数据
for(int i=0;i<m_students.StudentNum();i++)
{
if(index==0)
{
if(m_students.GetStudent(i).s_ID==tempstr)
indexlist.append(i); //记录列表中
}
if(index==1)
{
if(m_students.GetStudent(i).s_Name==tempstr)
indexlist.append(i); //记录列表中
}
if(index==2)
{
if(m_students.GetStudent(i).s_class==tempstr)
indexlist.append(i); //记录列表中
}
}
//判断列表是否为空
if(indexlist.isEmpty())
Show_Label2(QString("未找到%1为%2的学生信息").arg(sg1.Get_Comboboxtext()).arg(tempstr));
else Show_Label2(QString("成功找到%1为%2的学生信息!").arg(sg1.Get_Comboboxtext()).arg(tempstr));
Show_SelectTable();
}
else Show_Label2("查询操作已取消!");
}
//在选课信息视图下
else if(m_View_kind==1 || m_View_kind==3)
{
SelectDialog1 sg1;
sg1.setWindowTitle("课程信息查询");
int ret=sg1.exec();
if(ret==QDialog::Accepted)
{
int index=sg1.Get_Comboboxindex();//查询特征索引0为课程编号,1为课程名称
QString tempstr=sg1.Get_Value(); //查询特征值
//遍历数据
for(int i=0;i<m_students.GetStudent(m_row).s_courses.CourseNum();i++)
{
Course temp_c=m_students.GetStudent(m_row).s_courses.GetCourse(i);
if(index==0)
{
if(temp_c.c_ID==tempstr)
indexlist1.append(i); //记录列表中
}
if(index==1)
{
if(temp_c.c_Name==tempstr)
indexlist1.append(i); //记录列表中
}
}
//判断列表是否为空
if(indexlist1.isEmpty())
Show_Label2(QString("未找到%1为%2的课程信息").arg(sg1.Get_Comboboxtext()).arg(tempstr));
else Show_Label2(QString("成功找到%1为%2的课程信息!").arg(sg1.Get_Comboboxtext()).arg(tempstr));
Show_SelectTable();
}
else Show_Label2("查询操作已取消!");
}
else
{
TipsDialog tig;
tig.Tips_Show("请在学生信息视图或课程信息视图下进行此操作!!!");
tig.exec();
Show_Label2("查询失败!");
}
}
connect(ui->tableView->itemDelegate(),&QAbstractItemDelegate::closeEditor,this,&MainWindow::on_ShowInfotableView_changed); //信号与槽进行连接(后续可在tabelView中直接修改)
MainWindow::on_ShowInfotableView_changed()
代码如下:void MainWindow::on_ShowInfotableView_changed()
{
QModelIndex index = ui->tableView->currentIndex();
int col=index.column();
Student & temp_ss=m_students.GetStudent(m_row);
QVariant data;//数据
switch(m_View_kind)
{
case 0://学生信息视图
{
data=studentTableView->data(index);
switch(col)
{
case 0: //学号
temp_ss.s_ID=data.toString();
break;
case 1: //姓名
temp_ss.s_Name=data.toString();
break;
case 2: //班级
temp_ss.s_class=data.toString();
break;
case 3: //电话
temp_ss.ph_number=data.toString();
break;
case 4: //生日
temp_ss.birthday=data.toDate();
break;
case 5: //住址
temp_ss.adress=data.toString();
break;
default:
break;
}
Show_Table_s_changed();
Show_Label2("修改已保存!");
break;
}
case 1: //选课信息视图
{
Course & temp_c=temp_ss.s_courses.GetCourse(m_row1);
data=studentTableView->data(index);
switch(col)
{
case 0: //课程编号
temp_c.c_ID=data.toString();
break;
case 1: //课程名称
temp_c.c_Name=data.toString();
break;
case 2: //学分
temp_c.credit=data.toFloat();
break;
case 3: //学期
temp_c.term=data.toString();
break;
case 4: //教室
temp_c.c_room=data.toString();
break;
case 5: //成绩
temp_c.grade=data.toFloat();
break;
default:
break;
}
Show_Table_c_changed();
Show_Label2("修改已保存!");
break;
}
case 2: //学生信息查询视图
{
data=studentTableView->data(index);
switch(col)
{
case 0: //学号
temp_ss.s_ID=data.toString();
break;
case 1: //姓名
temp_ss.s_Name=data.toString();
break;
case 2: //班级
temp_ss.s_class=data.toString();
break;
case 3: //电话
temp_ss.ph_number=data.toString();
break;
case 4: //生日
temp_ss.birthday=data.toDate();
break;
case 5: //住址
temp_ss.adress=data.toString();
break;
default:
break;
}
Show_Table_sc_changed();
Show_Label2("修改已保存!");
break;
}
case 3: //课程信息查询视图
{
Course & temp_c=temp_ss.s_courses.GetCourse(m_row1);
data=studentTableView->data(index);
switch(col)
{
case 0: //课程编号
temp_c.c_ID=data.toString();
break;
case 1: //课程名称
temp_c.c_Name=data.toString();
break;
case 2: //学分
temp_c.credit=data.toFloat();
break;
case 3: //学期
temp_c.term=data.toString();
break;
case 4: //教室
temp_c.c_room=data.toString();
break;
case 5: //成绩
temp_c.grade=data.toFloat();
break;
default:
break;
}
Show_Table_sc_changed();
Show_Label2("修改已保存!");
break;
}
}
}