C++大作业总结(我的第一个界面程序)
也许是出于对计算机程序的着迷,从一开始学计算机我就想我得赶快写出一个界面程序来,那样就不只是一个使用软件的人了,而能算是一个可以写软件的人了。(原谅我这么土的想法)。以前大一的时候也看过“C语言也能干大事”,上学期开发过图书馆管理系统,不过同组的大牛根本没让我动手( ̄□ ̄||)。总之之前没有开发出什么界面程序。(其实写网页我也觉得很酷)。好了不再多说,下面是我这次课程设计的总结。
一、题目要求。
二、源代码编写说明
(一)普通类说明
1、user类
user类是消费者类。定义如下:
class user
{
public:
QString id; //id
QString psw; //password
QString address; //address
double money; //余额
double spend; //购物消费暂存
user();
user(QString ,QString, QString,double,double);
virtual ~user();
};
2、carrier类
consumer是送餐员类。
除了id、password的基本属性之外还有address(地址)、money(总钱数)、spend(一次购物中的总花费)等基本属性。
class carrier
{
public:
QString id; //id
QString psw; //password
int ordernum; //订单数量
double ordersum; //订单总金额
carrier();
carrier(QString ,QString,int ordernum, double orsersum);
};
3、order类
Order是订单类
除了id、password的基本属性之外还有ordernum;(待配送订单数目)、ordersum(待配送订单总钱数)等基本属性。
本类的函数有:
checkorder函数(查看自己的待配送订单)
markfinish函数(标记已完成订单)
4、food类
food是食物类,将在本程序中完成存储一个菜品的功能。
本类的基本属性有 name(菜品名称)、price(价格)、buynumber(购买数量),以及其他窗口相关属性。
class food
{
public:
QString name; //食物名称
QString pic_loc; //图片的文件名
double price; //价格
int buynumber; //购买量,显示订单时使用
food();
~food();
public slots:
void setbuynum(int); //跟购买按钮联系的槽
};
5、order类
本类是本程序中非常非常关键的一个类。它存放了跟订单有关的所有信息,消费者和送餐员都要访问这个类来完成添加订单、查看订单、标记已完成订单、查看已完成订单的功能。
class order
{
public:
int orderid; //订单号
QString consumer_id; //消费者id
QString consumer_address; //消费者地址
QString carrier_id; //送餐员id
int finish; //标识是否配送完毕
double ordersum; //订单总额
QVector<food> flist; //存放订单里的食物
int fnum; //食物种类数,读入文件的时候用
QString time; //下单时间
order();
virtual ~order();
};
(二)QT窗口类说明
1、mainwindow类
本窗口是登录窗口,定义如下。
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void initial();
Ui::MainWindow *ui;
QVector<user> usermap; //消费者信息容器
QVector<carrier> carmap; //送餐员信息容器
QVector<food> foodlist; //食品信息容器
QVector<order> orderlist; //订单信息容器
QPixmap pix0; //登陆界面图片
private slots:
void on_userlogin_clicked(); //登录按钮被点击
void on_pushButton_clicked(); //注册按钮被点击
};
2、fooditem类
Fooditem是要显示在订单和菜单widget里面的item,起着显示食品信息的作用。
定义如下:
class fooditem : public QWidget
{
Q_OBJECT
public:
explicit fooditem(QWidget *parent = 0);
~fooditem();
QString name; //食品名字
QString pic_loc; //图片信息
double price; //价格信息
int buynumber; //购买量
//初始化函数
void initial(QString&,QString&,double& ,int& ,QString);
signals:
void valueinc(QString); //“加一分”按钮点击时,发出信号
private slots:
void on_pushButton_clicked(); //“加一分”按钮点击
void resetbuynum(); //提交订单后,菜单显示数量复原
private:
Ui::fooditem *ui;
};
3、orderitem类
顾名思义,这是显示订单信息的窗口。定义如下:
class orderitem : public QWidget
{
Q_OBJECT
public:
int orderid; //订单号
int fnum; //订单里的食品种类数
QVector<food> flist; //存放食品的容器
QString consumer_id; //消费者id
QString consumer_address; //消费者地址
QString carrier_id; //送餐员id
int finish; //是否配送完毕
double ordersum; //订单总额
QString time; //下单时间
explicit orderitem(QWidget *parent = 0);
~orderitem();
void initial(order &ord,QString type);
signals:
void statechange(int); //标记按钮按下时,发出信号
private slots:
void on_confirm_clicked(); //标记按钮按下
private:
Ui::orderitem *ui;
};
4、charge类
Charge是充值窗口,定义如下;
class charge : public QWidget
{
Q_OBJECT
public:
explicit charge(QWidget *parent = 0);
~charge();
private slots:
void on_pushButton_clicked(); //提交按钮按下时,从文件中读入信息,与用户输入的数据比对,如果符合,修改金额并写文件
private:
Ui::charge *ui;
};
5、buywin类,购买窗口
class buywin : public QWidget
{
Q_OBJECT
public:
explicit buywin(QWidget *parent = 0);
~buywin();
void setinfo(int i); //告知窗口当前消费者的序号
void loadintolist(); //加载文件内容
void display_food(); //显示菜单
QString assign(); //分配任务给送餐员
void closeEvent(QCloseEvent *event); //定义关闭事件,关闭时打开登录窗口
signals:
void buywinclose(); //窗口关闭时发出信号
private slots:
void on_submitorder_clicked(); //提交订单按钮按下,生成订单并写入文件
void on_checkoder_clicked(); //查看订单按钮按下,从文件中读入信息并显示
void incbuynum(QString); //“加一份”按钮按下时发出信号
void on_charge_clicked(); //充值按按钮按下时打开充值窗口
void on_history_clicked(); //查看历史订单按钮按下时,懂文件中读入并显示
private:
Ui::buywin *ui;
int seq; //消费者序号
double spend; //已花费
QVector<carrier> bcarmap; //送餐员信息容器
QVector<food> bfoodlist; //菜单容器
QVector<order> borderlist; //订单容器
QVector<user> usermap; //消费者信息容器
QDateTime ctime; //下单时间
};
6、deliver类,送餐员窗口
class deliver : public QWidget
{
Q_OBJECT
public:
explicit deliver(QWidget *parent = 0);
void setinfo(QString&); //设置送餐员信息
void loadintolist(); //加载文件
void display(); //显示未完成、已完成订单
void closeEvent(QCloseEvent *event); //关闭事件
~deliver();
signals:
void deliverwclose(); //关闭事件的信号
private slots:
void on_markButton_clicked(); //标记按钮按下
void markfinish(int); //修改相应的标记位并写入文件
void on_checkorder_clicked(); //查看按钮按下
private:
Ui::deliver *ui;
QString id;
QVector<carrier> dcarmap; //送餐员信息容器
QVector<food> dfoodlist; //菜单容器
QVector<order> dorderlist; //订单容器
};
三、编写和调试记录
第一版:
本次实验所克服的困难是分层面的,从一开始对程序的基本逻辑搞不清楚,到后来的对程序界面和容错率的不断改进,我觉得每一个层面都有所收获。
一开始对于这个程序感觉无从下手,思考后决定先从大的功能入手,先定好有几个类,哪个功能有那个函数实现,这个函数在那个类里实现。在把这些想透彻了之后,便开始写代码,由于前些天编译原理的编程作业对vector的使用有了一定程度熟悉,在编写代码的时候在类和数据结构方面便都没有了太大的困难。写的时候还算比较顺畅,用了两天的空余时间写完了第一版要求全部的功能。
后来,在写完了代码编译的过程中修改了一些小的错误,记得全部写完了之后第一次编译时出现了六个错误,而过了不到半小时程序便编译成功能跑了,我感觉相对于大一时的自己,代码能力有了很大的提升。
一开始的整体思路并不完善,对于类的定义也不够正确。一开始我并没有定义专门的订单类,而是在消费者类和送餐员类中分别添加了vector<foodlist> 这个属性来实现订单的生成和分配,后来发现这样的设置导致消费者每次只能生成一个订单,送餐员每次只能分配一个订单,而且在让消费者个送餐员传送订单信息的时候搞的很复杂。后来考虑到这个问题,而且考虑到第二版的程序中要求能够查看历史订单,于是就想起了要把所有生成的订单放在一个统一的容器中,而且单独定义一个不同于Foodlist类的order类,在其中添加消费者的相关信息和送餐员的相关信息,让消费者和送餐员各取所需,发现这样的设置也比原来的设置实现起来更简单更清晰,于是很快的搞定了。
最后一个阶段的工作是对于程序小bug的调试,比如在有时候输入不符合要求会引起死循环,于是就在输入的入口提高容错率。
以上是从纵向和过程上来说我的收获,在“能力”的方面,我觉得自己的代码能力有了比较大的提高,对于C++类、函数的实现、类的多态和继承等方面都有新的认识。对于容器类vector的使用也更加熟练。
本次实验也有一个遗憾就是没有在规定时间内能做出图形界面,由于之前对QT不熟,我就决定先写出dos界面的程序,主要是怕写QT界面太慢完不成。结果写好了dos界面的程序,也快验收了,而且最近课程考试比较紧,QT界面的程序还没实现玩主要功能,不得不说是个遗憾,我希望自己能在第二次验收的时候做好图形界面版本。
第二版:
在写第二版有界面的程序的时候,花费了我大约两个星期的每个晚上的1个小时左右,期间遇到了各种错误和调整,最主要的调整一个是在显示菜单、订单的时候一开始实用的是tablewidget,当时还有考虑各种布局问题,浪费时间而且效果非常不好,而后来在同学的启发下,开始使用统一的fooditem窗口、orderitem窗口去显示食品和订单,果然效果好了很多,显得的比较专业了。其后遇到的一个大问题是我想用窗口类代替普通类的功能,也就是容器里也放置窗口类,结果在实践的过程中,报错,说Qwidget类不能复制,各种修改(用指针等等)无果,就放弃了这个想法继续保留普通类。
在重定义操作符、文件的使用方面,一开始在读入订单的时候,老是发生订单里的菜增加,重复的情况,后来发现,每次读一个订单,用的是临时变量torder.flist.push_back()函数,而读完一个订单以后该容器没有clear,导致重复的情况发生,修改了以后便成功了。
(上面的摘自我的报告,还是有一点参考意义的,等有机会再简化一下,突出一下问题和知识点)