源码上传至:https://github.com/data1213/QT_Studnt_Manager
需求:
1、在主窗口中菜单选项中设置查询菜单选项,能够跳转到查询界面。
2、设计查询界面,设置查询类型(按学生姓名、学号、院系)
3、从Qfile中获取数据源,匹配查询结果,并在tableview控件中显式
这里需要一个查询界面,先定义出来,定义为Dialog的窗口
query_students.ui中定义窗口控件:这里的tableview是model base中的
1 /****query_students.h*****/ 2 #ifndef QUERY_STUDENTS_H 3 #define QUERY_STUDENTS_H 4 5 #include <QDialog> 6 #include <QStandardItem> 7 #include <QStandardItemModel> 8 9 namespace Ui { 10 class Query_Students; 11 } 12 13 class Query_Students : public QDialog 14 { 15 Q_OBJECT 16 17 public: 18 explicit Query_Students(QWidget *parent = nullptr); 19 ~Query_Students(); 20 21 int read_from_file(); //获取文件中的学生信息数据源 22 void do_query(int index,QString text); //根据下拉框+lineEdit输入的信息进行开始查找匹配 23 void match_stud_info(int row,QStringList subs); //匹配信息,然后填充tableview控件之学生信息表格显示 24 void set_table_title(); //设置tableview控件数据之表头 25 private slots: 26 void start_to_query(); //响应"开始查找"按钮 27 28 private: 29 Ui::Query_Students *ui; 30 QList<QString> stud_info_list; //存放Qfile中所有读取到的学生信息,多条QString字符串构成的集合 31 32 QStandardItemModel* model; //表对象——存放tableview的数据 33 }; 34 35 #endif // QUERY_STUDENTS_H
在query_students构造方法中:
1>先将Qfile文件中所有学生信息读取出来,为什么要在此读取,而不是在点击 "开始查询"时读取。
开始查询,在实际情况中,可能会点击多次,如果绑定了读取文件操作,那么会多次读取,而在构造方法中,那么在查询窗口出来时,表示用户正要进行查询,所以有必要一次性读取全部信息,然后剩下的就是内存操作了,速度更快。
2>绑定"开始查询"按钮,响应开始查询匹配,然后,匹配到的学生信息,将被填充到tableview中
3>创建表对象,并且添加表头数据,这样,在查询窗口生成时,能够看到表头信息,知道可能有学生的哪些信息被显式。
1 Query_Students::Query_Students(QWidget *parent) :QDialog(parent),ui(new Ui::Query_Students) 2 { 3 ui->setupUi(this); 4 5 //创建查询窗口的时候,将文件数据全部获取到内存——stud_info_list中待用。 6 int res = read_from_file(); 7 if(res == -1){ 8 this->close(); //打开文件失败,关闭当前窗口 9 } 10 11 //绑定 “开始查询”按钮到槽函数 12 connect(this->ui->btn_query,SIGNAL(clicked()),this,SLOT(start_to_query())); 13 14 /* 15 创建一个表对象 16 */ 17 this->model = new QStandardItemModel(); 18 /* 19 为表的对应行、列锁定的表项填入数据 20 */ 21 //1、设置表头,setHorizontalHeaderItem不需要行参数(就是第一行),需要:列号+要显式的内容 22 //表头是需要在窗口显式出来的时候就显式的,而数据项是在点击“开始查询”之后才填入的。 23 this->set_table_title(); 24 //除表头外的数据后续添加... 25 26 //关联表对象与tableview控件,这样表的内容就显式到tableview控件上去了 27 this->ui->tableView->setModel(model); 28 29 }
表头数据以及列宽设置:
1 void Query_Students::set_table_title(){ 2 this->model->setHorizontalHeaderItem(0,new QStandardItem("姓名")); 3 this->model->setHorizontalHeaderItem(1,new QStandardItem("学号")); 4 this->model->setHorizontalHeaderItem(2,new QStandardItem("性别")); 5 this->model->setHorizontalHeaderItem(3,new QStandardItem("院系")); 6 this->model->setHorizontalHeaderItem(4,new QStandardItem("年龄")); 7 this->model->setHorizontalHeaderItem(5,new QStandardItem("爱好")); 8 9 this->ui->tableView->setColumnWidth(0,50); 10 this->ui->tableView->setColumnWidth(1,50); 11 this->ui->tableView->setColumnWidth(2,50); 12 this->ui->tableView->setColumnWidth(3,100); 13 this->ui->tableView->setColumnWidth(4,50); 14 this->ui->tableView->setColumnWidth(5,100); 15 }
效果显式:
从Qfile文件读取学生的信息操作:
1 //读取学生信息操作 2 int Query_Students::read_from_file(){ 3 4 QString line_info=""; 5 QFile file("stu.txt"); 6 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){ 7 QMessageBox::critical(this,"打开文件错误","确认"); 8 return -1; 9 } 10 QTextStream in(&file); 11 while (!in.atEnd()) { 12 line_info = in.readLine(); 13 this->stud_info_list.append(line_info); 14 } 15 //关闭文件 16 file.close(); 17 return 0; 18 }
开始查询:
1 void Query_Students::start_to_query(){ 2 3 //为了不显示上一次查询的结果,清空当前tableview数据,包括表头 4 this->model->clear(); 5 //重新设置表头 6 this->set_table_title(); 7 8 //获取当前准备查询的类型,以及lineEdit的内容 9 int methd = this->ui->cb_query->currentIndex(); 10 QString cnt = this->ui->le_query->text(); 11 this->do_query(methd,cnt); 12 }
利用界面的下拉框+lineEdit信息去匹配到,具体哪一条学生信息记录:
1 //匹配算法 2 void Query_Students::do_query(int index,QString text){ 3 //原始数据都在:QList<QString> stud_info_list; 4 //遍历 5 int row = 0; 6 for(int i=0;i<this->stud_info_list.length();i++){ 7 QString line = this->stud_info_list.at(i); //取出一条记录 8 //去掉开头和末尾的空格字符 9 line = line.trimmed(); 10 //分割 11 QStringList qlist = line.split(" "); 12 //匹配 13 switch(index){ 14 case 0: //按姓名查找 15 if(text == qlist.at(0)){ //qlist.at(0)就是文件中读取的一条记录被分割的姓名字符串 16 qDebug()<<line; 17 this->match_stud_info(row++,qlist); 18 } 19 break; 20 case 1: //按学号 21 if(text == qlist.at(1)){ //学号匹配 22 this->match_stud_info(row++,qlist); 23 qDebug()<<line; 24 } 25 break; 26 case 2: //按院系 27 if(text == qlist.at(3)){ //文本中存放院系:例如:ketty 10082 女 外语系 19 排球 羽毛球 28 this->match_stud_info(row++,qlist); 29 qDebug()<<line; 30 } 31 break; 32 default: 33 break; 34 35 } 36 } 37 }
匹配到具体的那条记录之后,需要将其填入tableview的表格中:
1 /* 2 当获取到文件中一行记录之后,并且转换为QStringList对象了,需要将其填入到指定的行、列标识的表中 3 setItem:一次只能填一个表格的信息,需要知道行号+列号+内容 4 */ 5 void Query_Students::match_stud_info(int row,QStringList subs){ 6 //前面五个都是1对1的,比如:姓名-->jerry 7 for(int i = 0;i<5;i++){ 8 this->model->setItem(row,i,new QStandardItem(subs.at(i))); 9 } 10 //对于爱好,由于是1对多的,需要拼接所有,然后显示在一个表格中 11 QString line_item =""; 12 for(int i=5;i<subs.length();i++){ 13 line_item +=subs.at(i)+','; 14 } 15 this->model->setItem(row,5,new QStandardItem(line_item)); 16 }
演示效果:
主窗口中绑定查询菜单和添加学生信息菜单:
1 #include "mainwindow.h" 2 #include "ui_mainwindow.h" 3 #include "addstudents.h" 4 #include <QDebug> 5 6 MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow) 7 { 8 ui->setupUi(this); 9 10 //连接创建的菜单到槽 11 connect(this->ui->actionAdd_Students,SIGNAL(triggered()),this,SLOT(show_my_Add_stud_Dialog())); 12 connect(this->ui->actionQuery_Students,SIGNAL(triggered()),this,SLOT(show_my_Query_stud_Dialog())); 13 } 14 15 MainWindow::~MainWindow() 16 { 17 delete ui; 18 qDebug()<<"主窗口完成退出"; 19 } 20 21 void MainWindow::show_my_Add_stud_Dialog(){ 22 AS.show(); 23 } 24 void MainWindow::show_my_Query_stud_Dialog(){ 25 QS.show(); 26 }