一.系统框架部分
1.在设计整个管理系统时,需首先搭建整体的大框架,理清各个数据模块之间的连接方式,其他小的功能在搭建大框架后实现即可
2.在qt中实现新增,删除,查找等功能时,可以仅使用一个dialog对话框,不同的功能可以通过改变对话框中的label来实现多态,集成使用同一个对话框
(个人认为使用label的标签值来功能集成化是一个亮点!也是整个程序功能实现的核心思想)
3.在存放数据时,尤其是有包含关系的数据类型,如:球员,场次;可以先实现球员,再场次,再创建一个包含场次信息的汇总类;即:从小到大依次实现。各种查找等功能均可以在数据汇总类中实现,即:数据汇总类有以下几个功能:数据汇总;新建等功能的集成实现;读取文件;写入文件;与mainwindow文件紧密联系,实现mainwindow与各种新建功能的连接(与mainwindow之间的联系非常重要!!这是整个程序的核心)
二.具体实现部分
1.展示对话框时,使用dialog.show()导致数据并未保存入public中,使用dialog.exec()解决此问题,且dialog.exec()为模态对话框,可以暂时阻止程序向下运行
2.如何实现对话框的集成化:mainwindow中包含对话框的头文件,且创建一个对话框对象m_dialog;mainwindow中建立各种不同的按键,在各个按键中建立槽函数,调用m_dailog的成员函数;其中成员函数需要改变m_dialog标签值,使之与mainwindow中的按键功能相对应;为实现功能集成化,在dialog中的”确定“按钮中也需要多态化(点击确定按钮时,通过判断m_dialog标签值,用if语句来实现不同的专属功能)
3.如何实现数据的显示功能:由于所有数据的汇总和功能实现均在汇总类dialog中,因此我们仍需主要依靠汇总类dialog。但是,我们在汇总类dialog中不大容易实现表格的制作,且表格的显示最好是放在mainwindow中的,因此我们可以在mainwindow中创建一个dialog类型的对象,在该对象中实现数据的筛选读取。但此时要保证当对话框关闭时,数据仍然存在着,可以尝试两种方式:1. 以exec()模态形式打开对话框;2. 在关闭对话框时,可以不用close()关闭函数,而采用hide()隐藏函数。 在保证数据存在后,我们在mainwindow中使用QStandardItemModel类型的模板指针来制作表格,显示数据。具体形式如下:
QStandardItemModel * sportsmanInforModel; //显示表格信息数据模型
sportsmanInforModel->clear(); //清空表格
sportsmanInforModel->setColumnCount(10); //设置表格为10列
//表头
QStringList templist;
templist.append("");
templist.append("场次编号"); //追加表头
templist.append("球队编号");
templist.append("球员编号");
sportsmanInforModel->setHorizontalHeaderLabels(templist); //将templist设置为表头
4.文件打开操作:该部分的aFileName与第8点的形参列表直接形成联系!!!
代码如下
QString curPath = "E:\\qt\\finalhomework";
QString dlgTitle = "选择一个文件";
QString filter = "文本文件(*.txt);;所有文件(*.*)";
QString aFileName = QFileDialog::getOpenFileName(this, dlgTitle, curPath, filter);
if(aFileName.isEmpty())
return;
readdatatofile(aFileName);
5.文件读取操作:在写入时,需要考虑是以向后追加,还是调用trunc()函数破坏性写入(当写入时,将整个文件全部清空);追加方式很方便,一般用于对文件直接进行操作,但局限性较大;truncate()函数更加适合有办法确定数据总数的情况,可使用间接法存入数据,即采用vector容器,可以直接对数据进行操作。经过尝试,发现本程序适合破坏性写入。此时可联想到c++大作业中的文件读写方式,即通过vector来储存文件中的各种数据,在写入的时候,可以先将文件中的所有数据全部读入vector中,通过专有函数对vector进行处理后,再将vector全部读入文件中。
代码如下:
bool m_DataDialog::readdatatofile(const QString &aReadFileName)//以向后追加的方式
{
QFile aFile(aReadFileName);
if(!aFile.exists()) //文件不存在
return false;
if(!aFile.open(QIODevice::ReadOnly | QIODevice::Text)) //以文本方式打开;同时判断是否打开
和执行打开方式
return false;
QTextStream aStream(&aFile); //用文本流读取文件
aStream.setCodec(QTextCodec::codecForName("system")); //显示汉字
for(;;) //该for循环非常重要!!!!它实现了读取数据是否完全的问题
{
int m_numbertemp;
aStream>>m_numbertemp; //读出数据的数目,然后再使用for循环挨个将数据push_abck即可
if(m_numbertemp>0) //判断此时读出的数目是否>0,依此来判断是否到文件末尾,而不是用atend()函数,经测试atend()不太好用
{
sessions temps;
for(int i=0;i<m_numbertemp;i++)
{
temps.readsessions(aStream);
p1_s.push_back(temps);
}
}
else
{
QMessageBox::information(this,"提示","文件读取全部完成!");
QMessageBox::information(this,"提示","读取完成后p1_s的大小为");
QMessageBox::information(this,"提示",QString::number(p1_s.size()));
break;
}
}
aFile.close();//关闭文件
return true;
}
6.在qt中debug时,常用QMessageBox::information(this,"提示","提示的内容")来判断程序中哪里有误,类似于c++中的断点
7.在文件读取中,出现了该读多少个数据的问题。解决方案:将数据的数目先读入文件,再以接受到的该数目来进行for循环读取。
三.界面美化部分
1.各个空间可通过移到Widget中,来实现垂直布局,水平布局等管控措施
2.可引入外部图片资源来美化该界面
四.效果演示:
1.主窗口
2.具体功能部分ui