软件工程综合实践专题 第一次作业
这是同学利用Qt写的一个订餐系统。该系统要求模拟网上的订餐系统,包含至少3-4个类以上,增加订单类,设计一个操作流程(界面),实现一组完整的基础功能。
源代码:
appearance.h
#ifndef APPEARANCE_H #define APPEARANCE_H #include <QDialog> #include "menu.h" namespace Ui { class Appearance; } class Appearance : public QDialog { Q_OBJECT public: explicit Appearance(QWidget *parent = 0); ~Appearance(); private slots: void on_pushButton_1_clicked(); void on_pushButton_2_clicked(); private: Ui::Appearance *ui; Menu *_menu; }; #endif // APPEARANCE_H
menu.h
1 #ifndef MENU_H 2 #define MENU_H 3 4 #include <QDialog> 5 #include"order.h" 6 #include <QMessageBox> 7 namespace Ui { 8 class Menu; 9 } 10 11 class Menu : public QDialog 12 { 13 Q_OBJECT 14 15 public: 16 explicit Menu(QString name,QWidget *parent = 0); 17 void start(); 18 ~Menu(); 19 20 private slots: 21 //20个button(-|+)的槽函数 22 void on_pushButton_l11_clicked(); 23 24 void on_pushButton_l12_clicked(); 25 26 void on_pushButton_r11_clicked(); 27 28 void on_pushButton_r12_clicked(); 29 30 void on_pushButton_l21_clicked(); 31 32 void on_pushButton_l22_clicked(); 33 34 void on_pushButton_r21_clicked(); 35 36 void on_pushButton_r22_clicked(); 37 38 void on_pushButton_l31_clicked(); 39 40 void on_pushButton_l32_clicked(); 41 42 void on_pushButton_r31_clicked(); 43 44 void on_pushButton_r32_clicked(); 45 46 void on_pushButton_l41_clicked(); 47 48 void on_pushButton_l42_clicked(); 49 50 void on_pushButton_r41_clicked(); 51 52 void on_pushButton_r42_clicked(); 53 54 void on_pushButton_l51_clicked(); 55 56 void on_pushButton_l52_clicked(); 57 58 void on_pushButton_r51_clicked(); 59 60 void on_pushButton_r52_clicked(); 61 62 int calculateMoney(); 63 void on_pushButton_e1_2_clicked(); 64 65 void on_pushButton_e1_clicked(); 66 67 private: 68 Ui::Menu *ui; 69 int _price[11]; 70 int _num[11]; 71 Order *_order; 72 int _total; 73 }; 74 75 #endif // MENU_H
order.h
1 #ifndef ORDER_H 2 2 #define ORDER_H 3 3 4 4 #include <QDialog> 5 5 #include <QMessageBox> 6 6 namespace Ui { 7 7 class Order; 8 8 } 9 9 10 10 class Order : public QDialog 11 11 { 12 12 Q_OBJECT 13 13 14 14 public: 15 15 explicit Order(QString name,int *num,int *price,int total,QWidget *parent = 0); 16 16 void generate(); 17 17 ~Order(); 18 18 signals: 19 19 void exitChild();//新建一个信号槽 20 20 private slots: 21 21 void on_pushButton_clicked(); 22 22 23 23 void on_pushButton_2_clicked(); 24 24 25 25 private: 26 26 Ui::Order *ui; 27 27 QString _dishes[11]; 28 28 int _num[11]; 29 29 int _price[11]; 30 30 int _name; 31 31 int _count; 32 32 }; 33 33 34 34 #endif // ORDER_H
appearance.cpp
1 #include "appearance.h" 2 #include "ui_appearance.h" 3 #include <QMessageBox> 4 #include<QDebug> 5 #include<QPixmap> 6 #include<QPalette> 7 #include<QPainter> 8 Appearance::Appearance(QWidget *parent) : 9 QDialog(parent), 10 ui(new Ui::Appearance) 11 { 12 ui->setupUi(this); 13 //提升窗口等级 14 this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint); 15 //设置背景 16 this->setStyleSheet("QWidget {background-image:url(:/new/bj/5.png)}"); 17 } 18 19 Appearance::~Appearance() 20 { 21 delete ui; 22 } 23 //进入菜单 24 void Appearance::on_pushButton_1_clicked() 25 { 26 //隐藏主界面 27 this->hide(); 28 //生成新的界面 29 _menu = new Menu(ui->lineEdit->text()); 30 _menu->show(); 31 } 32 //退出菜单 33 void Appearance::on_pushButton_2_clicked() 34 { 35 this->hide(); 36 QMessageBox::about(this,tr("提示信息"),tr("欢迎您下次使用~")); 37 this->close(); 38 }
menu.cpp
1 #include "menu.h" 2 #include "ui_menu.h" 3 #include<QDebug> 4 #include"appearance.h" 5 Menu::Menu(QString name,QWidget *parent) : 6 QDialog(parent), 7 ui(new Ui::Menu) 8 { 9 ui->setupUi(this); 10 //提升窗口等级 11 this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint); 12 //设置背景 13 this->setStyleSheet("QWidget {background-image:url(:/new/bj/5.png)}"); 14 //设置用户名 15 ui->label_e_0->setText(name); 16 //数据初始化 17 _price[1] = 8; 18 _price[2] = 12; 19 _price[3] = 18; 20 _price[4] = 16; 21 _price[5] = 22; 22 _price[6] = 22; 23 _price[7] = 8; 24 _price[8] = 12; 25 _price[9] = 12; 26 _price[10] = 38; 27 //这里是程序的开始 28 start(); 29 } 30 //初始化数据 31 void Menu::start() 32 { 33 ui->pushButton_l11->setEnabled(false); 34 ui->pushButton_l21->setEnabled(false); 35 ui->pushButton_l31->setEnabled(false); 36 ui->pushButton_l41->setEnabled(false); 37 ui->pushButton_l51->setEnabled(false); 38 ui->pushButton_r11->setEnabled(false); 39 ui->pushButton_r21->setEnabled(false); 40 ui->pushButton_r31->setEnabled(false); 41 ui->pushButton_r41->setEnabled(false); 42 ui->pushButton_r51->setEnabled(false); 43 //初始化数据 44 for(int i = 1;i<=10;i++) 45 _num[i]= 0; 46 _total = 0; 47 } 48 49 Menu::~Menu() 50 { 51 delete ui; 52 } 53 //下面是button(-|+)的响应函数;顺序:逐行,每一行先左后右 54 void Menu::on_pushButton_l11_clicked() 55 { 56 int num = ui->label_l12->text().toInt()-1; 57 ui->label_l12->setText(QString::number(num)); 58 if(!num) 59 ui->pushButton_l11->setEnabled(false); 60 _num[1]--; 61 calculateMoney(); 62 } 63 64 void Menu::on_pushButton_l12_clicked() 65 { 66 int num = ui->label_l12->text().toInt()+1; 67 ui->label_l12->setText(QString::number(num)); 68 if(num) 69 ui->pushButton_l11->setEnabled(true); 70 _num[1]++; 71 calculateMoney(); 72 } 73 74 void Menu::on_pushButton_r11_clicked() 75 { 76 int num = ui->label_r12->text().toInt()-1; 77 ui->label_r12->setText(QString::number(num)); 78 if(!num) 79 ui->pushButton_r11->setEnabled(false); 80 _num[2]--; 81 calculateMoney(); 82 } 83 84 void Menu::on_pushButton_r12_clicked() 85 { 86 int num = ui->label_r12->text().toInt()+1; 87 ui->label_r12->setText(QString::number(num)); 88 if(num) 89 ui->pushButton_r11->setEnabled(true); 90 _num[2]++; 91 calculateMoney(); 92 } 93 //第二行 94 void Menu::on_pushButton_l21_clicked() 95 { 96 int num = ui->label_l22->text().toInt()-1; 97 ui->label_l22->setText(QString::number(num)); 98 if(!num) 99 ui->pushButton_l21->setEnabled(false); 100 _num[3]--; 101 calculateMoney(); 102 } 103 104 void Menu::on_pushButton_l22_clicked() 105 { 106 int num = ui->label_l22->text().toInt()+1; 107 ui->label_l22->setText(QString::number(num)); 108 if(num) 109 ui->pushButton_l21->setEnabled(true); 110 _num[3]++; 111 calculateMoney(); 112 } 113 114 void Menu::on_pushButton_r21_clicked() 115 { 116 int num = ui->label_r22->text().toInt()-1; 117 ui->label_r22->setText(QString::number(num)); 118 if(!num) 119 ui->pushButton_r21->setEnabled(false); 120 _num[4]--; 121 calculateMoney(); 122 } 123 124 void Menu::on_pushButton_r22_clicked() 125 { 126 int num = ui->label_r22->text().toInt()+1; 127 ui->label_r22->setText(QString::number(num)); 128 if(num) 129 ui->pushButton_r21->setEnabled(true); 130 _num[4]++; 131 calculateMoney(); 132 } 133 //第三行 134 void Menu::on_pushButton_l31_clicked() 135 { 136 int num = ui->label_l32->text().toInt()-1; 137 ui->label_l32->setText(QString::number(num)); 138 if(!num) 139 ui->pushButton_l31->setEnabled(false); 140 _num[5]--; 141 calculateMoney(); 142 } 143 144 void Menu::on_pushButton_l32_clicked() 145 { 146 int num = ui->label_l32->text().toInt()+1; 147 ui->label_l32->setText(QString::number(num)); 148 if(num) 149 ui->pushButton_l31->setEnabled(true); 150 _num[5]++; 151 calculateMoney(); 152 } 153 154 void Menu::on_pushButton_r31_clicked() 155 { 156 int num = ui->label_r32->text().toInt()-1; 157 ui->label_r32->setText(QString::number(num)); 158 if(!num) 159 ui->pushButton_r31->setEnabled(false); 160 _num[6]--; 161 calculateMoney(); 162 } 163 164 void Menu::on_pushButton_r32_clicked() 165 { 166 int num = ui->label_r32->text().toInt()+1; 167 ui->label_r32->setText(QString::number(num)); 168 if(num) 169 ui->pushButton_r31->setEnabled(true); 170 _num[6]++; 171 calculateMoney(); 172 } 173 //第四行 174 void Menu::on_pushButton_l41_clicked() 175 { 176 int num = ui->label_l42->text().toInt()-1; 177 ui->label_l42->setText(QString::number(num)); 178 if(!num) 179 ui->pushButton_l41->setEnabled(false); 180 _num[7]--; 181 calculateMoney(); 182 } 183 184 void Menu::on_pushButton_l42_clicked() 185 { 186 int num = ui->label_l42->text().toInt()+1; 187 ui->label_l42->setText(QString::number(num)); 188 if(num) 189 ui->pushButton_l41->setEnabled(true); 190 _num[7]++; 191 calculateMoney(); 192 } 193 194 void Menu::on_pushButton_r41_clicked() 195 { 196 int num = ui->label_r42->text().toInt()-1; 197 ui->label_r42->setText(QString::number(num)); 198 if(!num) 199 ui->pushButton_r41->setEnabled(false); 200 _num[8]--; 201 calculateMoney(); 202 } 203 204 void Menu::on_pushButton_r42_clicked() 205 { 206 int num = ui->label_r42->text().toInt()+1; 207 ui->label_r42->setText(QString::number(num)); 208 if(num) 209 ui->pushButton_r41->setEnabled(true); 210 _num[8]++; 211 calculateMoney(); 212 } 213 //第五行 214 void Menu::on_pushButton_l51_clicked() 215 { 216 int num = ui->label_l52->text().toInt()-1; 217 ui->label_l52->setText(QString::number(num)); 218 if(!num) 219 ui->pushButton_l51->setEnabled(false); 220 _num[9]--; 221 calculateMoney(); 222 } 223 224 void Menu::on_pushButton_l52_clicked() 225 { 226 int num = ui->label_l52->text().toInt()+1; 227 ui->label_l52->setText(QString::number(num)); 228 if(num) 229 ui->pushButton_l51->setEnabled(true); 230 _num[9]++; 231 calculateMoney(); 232 } 233 234 void Menu::on_pushButton_r51_clicked() 235 { 236 int num = ui->label_r52->text().toInt()-1; 237 ui->label_r52->setText(QString::number(num)); 238 if(!num) 239 ui->pushButton_r51->setEnabled(false); 240 _num[10]--; 241 calculateMoney(); 242 } 243 244 void Menu::on_pushButton_r52_clicked() 245 { 246 int num = ui->label_r52->text().toInt()+1; 247 ui->label_r52->setText(QString::number(num)); 248 if(num) 249 ui->pushButton_r51->setEnabled(true); 250 _num[10]++; 251 calculateMoney(); 252 } 253 //计算金额 254 int Menu::calculateMoney() 255 { 256 int total = 0; 257 for(int i = 1;i<=10;i++){ 258 total+=_price[i]*_num[i]; 259 //qDebug()<<"this is "<<i<<" price: "<<_price[i]<<" num: "<<_num[i]; 260 } 261 _total = total; 262 ui->label_e_2->setText(QString::number(total)); 263 } 264 //清空购物车 265 void Menu::on_pushButton_e1_2_clicked() 266 { 267 ui->label_l12->setText("0"); 268 ui->label_r12->setText("0"); 269 ui->label_l22->setText("0"); 270 ui->label_r22->setText("0"); 271 ui->label_l32->setText("0"); 272 ui->label_r32->setText("0"); 273 ui->label_l42->setText("0"); 274 ui->label_r42->setText("0"); 275 ui->label_l52->setText("0"); 276 ui->label_r52->setText("0"); 277 ui->label_e_2->setText("0"); 278 start(); 279 } 280 //订单生成 281 void Menu::on_pushButton_e1_clicked() 282 { 283 if(_total == 0) 284 QMessageBox::about(this,tr("提示信息"),tr("您未点菜~")); 285 else 286 { 287 this->hide(); 288 _order = new Order(ui->label_e_0->text(),_num,_price,_total); 289 _order->show(); 290 //当订单_order关闭时,重新让父窗口menu show出来 291 connect(_order,SIGNAL(exitChild()),this,SLOT(show())); 292 } 293 }
order.cpp
1 #include "order.h" 2 #include "ui_order.h" 3 4 Order::Order(QString name,int *num,int *price,int total,QWidget *parent) : 5 QDialog(parent), 6 ui(new Ui::Order) 7 { 8 ui->setupUi(this); 9 //提升窗口等级 10 this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint); 11 //设置背景 12 this->setStyleSheet("QWidget {background-image:url(:/new/bj/6.png)}"); 13 //设置参数 14 ui->label_1->setText(name+"的订单"); 15 _count = 0; 16 for(int i = 1;i<=10;i++){ 17 _price[i] = price[i]; 18 _num[i] = num[i]; 19 if(_num[i]) 20 _count++; 21 } 22 _dishes[1] = "醋溜白菜"; 23 _dishes[2] = "麻婆豆腐"; 24 _dishes[3] = "宫保鸡丁"; 25 _dishes[4] = "干锅菜花"; 26 _dishes[5] = "鱼香肉丝"; 27 _dishes[6] = "水煮肉片"; 28 _dishes[7] = "酸辣土豆丝"; 29 _dishes[8] = "蒜蓉油麦菜"; 30 _dishes[9] = "干煸四季豆"; 31 _dishes[10] = "沸腾水煮鱼"; 32 generate(); 33 ui->label_3->setText("总计:"+QString::number(total)); 34 } 35 36 void Order::generate() 37 { 38 //自适应 39 ui->textBrowser->setGeometry(50,90,231,24.1*_count); 40 ui->label_2->setGeometry(50,ui->textBrowser->pos().y()+55+24*_count,231,40); 41 ui->label_3->setGeometry(140,99+24*_count,160,40); 42 ui->pushButton->setGeometry(210,ui->label_2->pos().y()+60,90,30); 43 ui->pushButton_2->setGeometry(40,ui->label_2->pos().y()+60,90,30); 44 this->setGeometry(600,300,331,260+24*_count); 45 46 QString context = ""; 47 for(int i = 1;i<=10;i++) 48 if(_num[i]) 49 context +=_dishes[i]+" *"+QString::number(_num[i])+" "; 50 _count /= 1.3; 51 context += "米饭 *"+QString::number(_count); 52 ui->textBrowser->setText(context); 53 } 54 55 Order::~Order() 56 { 57 delete ui; 58 } 59 //返回菜单 60 void Order::on_pushButton_clicked() 61 { 62 this->close(); 63 emit exitChild(); 64 } 65 //确定订单 66 void Order::on_pushButton_2_clicked() 67 { 68 this->hide(); 69 QMessageBox::about(this,tr("提示信息"),tr("请稍后,您的菜正在烹饪中~")); 70 this->close(); 71 }
main.cpp
1 #include "appearance.h" 2 #include <QApplication> 3 4 int main(int argc, char *argv[]) 5 { 6 QApplication a(argc, argv); 7 Appearance w; 8 w.show(); 9 10 return a.exec(); 11 }
一、编码风格
首先附上Google 开源项目风格指南 (中文版)——C++风格指南以作参考:
https://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/contents/
规则的作用就是避免混乱。因此编码规范不仅告诉我们要怎么做, 还告诉我们为什么要这么做,哪些情况下可以不这么做,并且如何权衡其利弊。对比这份编码规范,发现这位同学的编程风格良好,变量命名规范,代码思路清楚、结构清晰,有很强的可读性,头文件具有#define保护,使用标准的头文件包含顺序增强了可读性, 避免了隐藏依赖。但美中不足的是有时候会忽略一些诸如“左大括号总在最后一个参数同一行的末尾处, 不另起新行”,“右圆括号和左大括号间总是有一个空格”,“if-else须同时具有大括号”,“格式应对齐”的小细节。
二、功能实现
首先通过拖拽组件的方式,初步构建系统的可视化页面,然后再对各个组件进行必要的编程。
首页界面可以键入用户名,用户可以选择进入或退出点餐页面,若进入则跳转到菜单界面进行进一步的操作,若不进入则退出系统。
菜单界面可以看到菜品的名称及价格信息,用户可以根据自己的需求通过“+”“-”button对菜品数量进行更改,当用户对自己的点餐情况不满意时可以点击“清空购物车”button让所有菜品数目归零,完成点餐后即可点击“生成订单”button跳转到订单界面对自己的点餐结果进行核实,若用户在所有菜品数目均为零的情况下点击“生成订单”button,则会提示用户“您未点餐”。
订单界面中不仅有用户的订单信息,用户还可以返回到菜单界面对订单进行修改,确认订单信息后点击“确定”button退出订餐系统。
三、改进方案
1. 异常处理
在使用该系统的过程中发现,该程序虽对一些出现的异常进行了处理,例如在菜单界面,当单个菜品数目为零时便不能继续减少,且当所有菜品数目均为零的情况下不能生成订单;但也存在一些问题,例如在首界面要求输入用户名时,即使用户名为空也可以进入到菜单界面。这里应该有一定的约束,确保用户只有在输入了用户名以后才能对该系统进行使用。
2. 界面问题
首先,建议菜单界面中添加通过键入直接对菜品数量进行更改的编辑方式,而不是只能通过点击“+”“-”的button对菜品数目进行更改,这样能提升一些需求量大的用户的使用体验,除此之外还应对菜品添加相应的实物图片,使用户更好地了解菜品以便做出更好的选择。
其次,建议订单界面的订餐明细分为三列,分别为“菜名”,“单价”,“数量”,每列的第一个字对其,字体稍大稍粗一些,方便用户对自己的点餐结果进行核实,并且再“返回”button下标注“修改”,以提醒用户可以对当前订单进行进一步的增删改等修改。
3. 输入输出
首先,菜单信息应从文件中导入,而不是直接添加在程序里,这样会造成店家对菜单更新、修改时的不便。
其次,订单生成后应该存入文件中,这样才能方便店家对订单进行管理,以及后续的统计工作等,并且应当使生成的订单信息能够通过外接的设备打印出来。
4. 功能补充
首先,在用户登录界面可以添加通过手机号及验证码登录的方式,这样一是省去了用户注册的麻烦,二又确保了每个用户的唯一性。
其次,该系统作为一个订餐系统,除了具备点餐功能外,还应拥有支付功能,因此后续可以尝试接入第三方支付软件的接口以确保订餐功能的完整性。除此之外,还应该添加一个“留言备注”功能方便客户向店家表达自己的需求,提高用户使用感。
四、心得体会
首先,在创建一个新的系统或产品时,进行详细的需求分析以确定顾客的需要是十分必要的。这能让我们分析和寻求新系统的解决方法来确定新系统的目的、范围、定义和功能。
其次,在编程过程中我们应该遵守编程规范以方便他人的阅读及日后对软件的维护等。
再者,在编程的同时应该对软件进行测试,一是能够及时发现程序错误并对其进行改正,二是能对系统或产品是否能满足设计要求进行评估以及时调整编程的方向。