本文为视频教程[1]的笔记。
目录
一、计算器介绍
1. 界面介绍
2. 功能介绍
二、计算器实现
1. 界面设计(View)
2. 内部方法设计(Model)
3. 页面与内部的交互实现(Control)
三、参考文档
包含16个按钮和一个文本显示框。
按钮选择“Push Button”,显示屏选择“LCD Number”。
(1)可对整数进行四则运算,仅能实现2个数之间的运算。例:2+2=4,不能计算2+2+2=6。
(2)按钮“C”可清除屏幕内容。
(3)出现不合法输入并按“=”号后,屏幕显示“-1”。
采用类MVC模式实现,Qt安装参考[2],这里使用的是5.9.0版本。
新建项目:
选择创建桌面Qt应用:
项目名称“exprDemo”:
基类选择“QDialog”对话框,类名“expr”,勾选“创建界面”:
双击打开“expr.ui”,设计计算器页面:
设置画布大小,选中画布,在右下角的属性中设置:
添加显示屏“LCD Number”和16个按钮:
效果如下:
对按钮进行布局设置,框选所有按钮,选择“栅格布局”:
在右上角全选所有按钮,修改属性:
选中整个按钮组,在画布中拉取合适的大小,可看到按钮大小随着按钮组大小而同步变化:
选中整个画布,选择“垂直布局”:
在属性中设置窗口名称“计算器”:
设置布局比例“3:7”:
运行程序查看效果:
修改计算器所有按钮显示名称:
修改变量名称:
所有名称如下图所示:
实现四则运算的代码,相关的代码文件为“model.h”和“model.cpp”。
右键该项目,选择“添加新文件”:
创建 c++ 文件:
命名为“model”:
在“model.h”中,定义需使用的方法和变量:
#ifndef MODEL_H
#define MODEL_H
#include
class model
{
public:
model();
// 方法
void setNum1(int num);
void setNum2(int num);
void setFlag(QString flag);
QString doExpr();
private:
// 定义变量 num1 (+=*/) num2
int num1;
int num2;
QString flag;
};
#endif // MODEL_H
在“model.cpp”中实现这些构造方法的定义:
#include "model.h"
model::model()
{
// 初始化
this->num1 = 0;
this->num2 = 0;
}
// 定义方法,对应model.h中的定义
void model::setNum1(int num)
{
this->num1 = num;
}
void model::setNum2(int num)
{
this->num2 = num;
}
void model::setFlag(QString flag)
{
this->flag = flag;
}
// 当用户点击"="号时调用该函数
QString model::doExpr()
{
double result = 0.0;
// switch不能用QStirng,这里用if
if(this->flag=="+"){
result = this->num1 + this->num2;
}else if(this->flag=="-"){
result = this->num1 - this->num2;
}else if(this->flag=="*"){
result = this->num1 * this->num2;
}else if(this->flag=="/"){
// 除数为0的情况
if(this->num2==0){
return "-1";
}
result = (this->num1)*1.0 / this->num2;
}else{
// 把int类型转化成string类型
// 1. str = QString::number(num);
// 2. str = setNum(num);
return QString::number(this->num1);
}
return QString::number(result);
}
因为输入只能是整数,因此只有在除法时才可能出现小数,故除数运算时 *1.0,转化为小数。
整个计算器的大致实现逻辑如下:
(1)在计算器上按顺序点击“数字、符号、数字”,把该数和符号分别获取并存入num1, flag和num2中。
(2)调用model中的方法进行运算,获取运算结果result。
(3)将结果result显示在ui界面的显示屏上。
该部分相关的代码文件为“expr.h”和“expr.cpp”。
在“expr.h”的private中定义,并引入对应头文件:
#include
#include "model.h"
...
private:
// 屏幕内容
QString tmp;
// 界面对象和核心功能对象
Ui::expr *ui;
model * mode;
添加槽函数,回到ui界面,右键数字“0”按钮,选择“转到槽”:
选择 点击 信号:
可以发现“expr.h”和“expr.cpp”中自动添加了对应内容:
对所有按钮都执行上述操作。
在“expr.cpp”中,新建model,并设置显示屏的默认值为0:
expr::expr(QWidget *parent) :
...
{
...
// 新建model,设置显示屏的默认值为0
this->mode = new model;
this->tmp = "";
}
tmp存储的是当前显示屏上的值,在不进行任何操作时,显示屏默认显示0,但tmp值为空。
对于点击按钮实现的效果分别如下:
(1)当按到0-9时
对于槽函数0,有:
void expr::on_btn_0_clicked()
{
// 第一个数是0时不会叠加0
if(this->tmp != ""){
// 拼接字符串
this->tmp += this->ui->btn_0->text();
// 把它显示出来
this->ui->lcd_display->display(this->tmp);
}
}
其中这里的display(s)方法是把字符串s表示的数字显示到LCD屏上:
对于槽函数1-9,有:
void expr::on_btn_1_clicked()
{
this->tmp += this->ui->btn_1->text();
this->ui->lcd_display->display(this->tmp);
}
只需修改第一条语句的btn_1为对应按钮名即可。
运行效果图:
(2)当按到四则运算符(+-*/)时
因为计算器只是实现2个数的运算,因此,在单个式子计算过程中只存在一个运算符,该运算符输入前屏幕上的数即为num1。
在该槽函数中,需要存储num1和flag的值:
void expr::on_btn_plus_clicked()
{
// 用于检测是否转化成功
bool ok;
// 1. 把当前屏幕上显示的string转为int存在num中
int num = this->tmp.toInt(&ok);
// 2. 当点击"+"号时,把num1的值设置为num
this->mode->setNum1(num);
// 3. 清除当前屏幕
this->tmp = "";
// 4. 记录点击的运算符
QString ex = this->ui->btn_plus->text();
this->mode->setFlag(ex);
}
对于 -*/ ,代码相同,只需把倒数第2行的btn_plus改成对应的按钮名称。
(3)当按到 = 符号时
因为计算器只是实现2个数的运算,因此,在 = 号前屏幕上显示的数即为num2。
在该槽函数中,需要存储num2的值,并根据已有的num1, num2, flag计算出最后的结果result,显示在屏幕上:
void expr::on_btn_equal_clicked()
{
// 1. 获取num2
bool ok;
int num = this->tmp.toInt(&ok);
this->mode->setNum2(num);
// 2. 计算num1和num2的运算结果
QString res = this->mode->doExpr();
// 3. 显示计算结果
this->ui->lcd_display->display(res);
// 4. 清除tmp内容,避免影响后续计算
this->tmp = "";
}
运行效果图:
(4)当按到清除符号(C)时
功能很简单,把当前屏幕上的内容置为0,同时把tmp置为空。
因为2个数字和符号反正在下次计算时会重新存储,即使之前有值也会被覆盖,所以不用管:
void expr::on_btn_c_clicked()
{
// 清除第一个计算数
this->tmp = "";
// 显示屏清0
this->ui->lcd_display->display(0);
}
此处display(n)用法:
运行效果图:
[1] Qt5教程(计算器篇)
[2] Qt下载(多种下载通道+所有版本)