计算机软件实习项目一 简单计算器 (Qt实现计算器界面) 12-5

UI用户界面

使用Qt Designer对计算器的界面进行制作

界面设计

  界面由22个按钮和1个线型编辑器组成,去除了菜单栏和状态栏。仿照苹果计算器,整体配色为黑、灰、橙;背景为黑色,数字、字母或符号为白色;更改了软件的名字以及软件的图标。

功能描述

C:清楚当前表达式和计算结果的历史记录
H:循环查看计算结果的历史记录
←:退格
CE:清除当前表达式
其他运算符和操作数:输入对应的字符

界面浏览

在这里插入图片描述

新功能

1.小数点前后自动补0

输入 “2.” 按下 ‘+’ 号会自动补0变成 “2.0+”,再输入 “.3” 会自动补0变成0.3
在这里插入图片描述

2.加减乘除自动切换

输入 “2*” 后输入 ‘/’ 或 ‘+’ 会自动变换当前符号。
在这里插入图片描述

3.不允许的操作按了不会生效

一个数字有小数点了就不能再按小数点,这时也按小数点也不会生效在这里插入图片描述
括号里不为空
在这里插入图片描述

4.历史记录循环查看

  计算若干表达式后按 ‘H’ 键,查看计算历史记录,第一次案会返回最近一次的计算结果,再按一次返回上上次的计算结果,以此类推;当到达最后一条也就是最早的计算记录的时候再按下 ‘H’ 键,则会返回最近一次的计算记录,也就是说这个记录是可以循环查询的。并且每当有一个新的结果产生时,再一次按下 ‘H’ 键还会返回最近一次的计算记录。
在这里插入图片描述

dbug

1.除0

通过修改程序使得原本除0会崩溃的程序变成了输出inf
在这里插入图片描述

2.负数运算

把负号和减号区分开,这里-4当成一个整体,计算结果正确
在这里插入图片描述

3.一个数只能有一个小数点

原代码一个数可以有多个小数点如2.33.44,修改代码后一个数不可输入多个小数点
在这里插入图片描述

4.无记录时查看记录出错

无记录时按下 ‘H’ 键会报错,修改后不做任何操作程序正常运行
在这里插入图片描述

按钮样式

  通过Qt Designer编辑按钮的样式表,设置按钮的背景颜色以及包边,鼠标悬停在按钮上的颜色以及按下按钮的颜色。
在这里插入图片描述

QPushButton{
	background-color: rgb(180, 180, 180);
	border:1px solid gray;
}
QPushButton:hover{
	background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgb(230, 230, 230), stop:1 rgb(180, 180, 180));
}
QPushButton:pressed{
	background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgb(180, 180, 180), stop:1 rgb(230, 230, 230));
}
效果

除号 ‘/’ 为未选中效果,乘号’×’ 为按下效果
在这里插入图片描述

LineEdit样式

  通过Qt Designer编辑按钮的样式表,设置线性编辑框的背景颜色为黑色,和主窗口相同;设置无边框;设置文字颜色为白色;设置文本为纵向居中对齐,横向右对齐。
在这里插入图片描述

效果

在这里插入图片描述

代码实现

枚举变量

定义枚举变量,区分不同的按钮

//枚举按键类型
enum BtnType
{
	Num,	//数字类型
	Op,		//运算符
	Dot,	//点
	Equal,	//等于
	Back,	//退格
	Clear,	//清除
	Empty,	//清空
	History,//历史记录
	Bracket //括号 
};
QtGuiApplication类的声明
class QtGuiApplication : public QMainWindow
{
	//支持信号和槽
	Q_OBJECT

public:
	//构造函数
	QtGuiApplication(QWidget *parent = Q_NULLPTR);

private:
	Ui::QtGuiApplicationClass ui;
	//当前串
	QString str;
	//当前数字
	QString cnum;
	//历史记录
	QStringList list;
	//记录按了几下history
	int k;

// 声明槽函数
public slots:
	void OnClicked(BtnType _type, QString _btn);
	
};
QtGuiApplication类的定义

  构造函数里对窗口名字、图标进行修改,对成员变量进行初始化,对按钮进行绑定

	QtGuiApplication::QtGuiApplication(QWidget *parent): 
	QMainWindow(parent)
{
	ui.setupUi(this);
	setWindowTitle("LuoHan Calculator v1.0");
	setWindowIcon(QIcon("A3.png"));

	//初始化成员变量
	this->str = "";
	//记录按了几下history
	this->k = 0;


	//数字按钮绑定
	connect(ui.pushButton_00, &QPushButton::clicked, [this]() {OnClicked(Num, "0"); });
	connect(ui.pushButton_01, &QPushButton::clicked, [this]() {OnClicked(Num, "1"); });
	connect(ui.pushButton_02, &QPushButton::clicked, [this]() {OnClicked(Num, "2"); });
	connect(ui.pushButton_03, &QPushButton::clicked, [this]() {OnClicked(Num, "3"); });
	connect(ui.pushButton_04, &QPushButton::clicked, [this]() {OnClicked(Num, "4"); });
	connect(ui.pushButton_05, &QPushButton::clicked, [this]() {OnClicked(Num, "5"); });
	connect(ui.pushButton_06, &QPushButton::clicked, [this]() {OnClicked(Num, "6"); });
	connect(ui.pushButton_07, &QPushButton::clicked, [this]() {OnClicked(Num, "7"); });
	connect(ui.pushButton_08, &QPushButton::clicked, [this]() {OnClicked(Num, "8"); });
	connect(ui.pushButton_09, &QPushButton::clicked, [this]() {OnClicked(Num, "9"); });

	//运算符按钮绑定
	connect(ui.pushButton_plus, &QPushButton::clicked, [this]() {OnClicked(Op, "+"); });
	connect(ui.pushButton_minus, &QPushButton::clicked, [this]() {OnClicked(Op, "-"); });
	connect(ui.pushButton_multiply, &QPushButton::clicked, [this]() {OnClicked(Op, "*"); });
	connect(ui.pushButton_divide, &QPushButton::clicked, [this]() {OnClicked(Op, "/"); });
	connect(ui.pushButton_leftbracket, &QPushButton::clicked, [this]() {OnClicked(Bracket, "("); });
	connect(ui.pushButton_rightbracket, &QPushButton::clicked, [this]() {OnClicked(Bracket, ")"); });

	//其他按钮
	connect(ui.pushButton_BACKSPACE, &QPushButton::clicked, [this]() {OnClicked(Back, "Back"); });
	connect(ui.pushButton_CE, &QPushButton::clicked, [this]() {OnClicked(Clear, "Clear"); });
	connect(ui.pushButton_Dot, &QPushButton::clicked, [this]() {OnClicked(Dot, "."); });
	connect(ui.pushButton_equal, &QPushButton::clicked, [this]() {OnClicked(Equal, "="); });
	connect(ui.pushButton_C, &QPushButton::clicked, [this]() {OnClicked(Empty, "Empty"); });
	connect(ui.pushButton_History, &QPushButton::clicked, [this]() {OnClicked(History, "History"); });
}
槽函数的定义

因为功能较单一,我只定义了一个槽函数对所有按钮进行操作

void QtGuiApplication::OnClicked(BtnType _type, QString _btn)

每按下一个按钮就初始化如下变量:

Calculate()对象用于计算表达式
result用于存放二元运算的结果
temp指向当前表达式的最后一个字符
history为当前历史记录
flag1表示:有无多个小数点
flag2表示:小数点前有无数字

	Calculate calculator = Calculate();
	string result = "";
	QString temp = str.right(1);
	QString history = "";
	//一个数有无多个小数点;
	int flag1 = 0;
	//小数点前有无数字;
	int flag2 = 0;

接下来就是判断按钮的类型用一个switch语句即可

switch (_type)

如果当前按钮是 数字:
① 如果有小数点且小数点前无数字就在小数点前补0
② 否则直接加上这个数字

case Num:
		//如果数字前面是小数点且小数点前面没有数字就补0
		if (temp == ".") {
			for (int i = str.length() - 1; i >= 0; i--) {
				if (str.at(i) == "+" || str.at(i) == "-" || str.at(i) == "*" || str.at(i) == "/" || str.at(i) == "(" || str.at(i) == ")") {
					break;
				}
				if (str.at(i) == "0"|| str.at(i) == "1" || str.at(i) == "2" || str.at(i) == "3" || str.at(i) == "4" || str.at(i) == "5" || str.at(i) == "6" || str.at(i) == "7" || str.at(i) == "8" || str.at(i) == "9") {
					flag2 = 1;
					break;
				}
			}
		}
		if (temp=="." && flag2 == 0) {
			//补0
			str = str.insert(str.length() - 1, "0");
			str += _btn;
			break;
		}
		str += _btn;
		break;

如果当前按钮是 运算符:
① 如果是小数点就补0
② +、-、*、/ 可替换

case Op:
		//如果前面是小数点补0
		if (temp == ".") {
			str += "0";
		}
		//运算符规则
		if (temp.compare("+") == 0 || temp.compare("-") == 0) {
			if (_btn.compare("-") == 0 || _btn.compare("+") == 0 || _btn.compare("*") == 0 || _btn.compare("/") == 0 ) {
				str = str.replace(str.length() - 1, 1, _btn);
				break;
			}
		}
		if ((temp.compare("*") == 0 || temp.compare("/") == 0)) {
			if (_btn.compare("*") == 0 || _btn.compare("/") == 0 || _btn.compare("+") == 0) {
				str = str.replace(str.length() - 1, 1, _btn);
				break;
			}
			if (_btn.compare("-") == 0) {
				str += _btn;
				break;
			}
		}
		str += _btn;
		break;

如果当前按钮是 ‘(’ 或 ‘)’:
① 如果括号里没东西什么也不做
② 否则加上括号

case Bracket:
		if (temp.compare("(")==0 && _btn.compare(")") == 0) {
			break;
		}
		str += _btn;
		break;

如果当前按钮是 ‘.’:
① 如果前面有括号什么也不做
② 如果前面有小数点也什么都不做

case Dot:
		if (temp.compare("(") == 0||temp.compare(")") == 0) {
			break;
		}
		for (int i = str.length() - 1; i >= 0;i--) {
			if (str.at(i) == "+"|| str.at(i) == "-" || str.at(i) == "*" || str.at(i) == "/" || str.at(i) == "(" || str.at(i) == ")") {
				break;
			}
			if (str.at(i) == ".") {
				flag1 = 1;
				break;
			}
		}
		if (flag1 == 1)break;
		str += _btn;
		break;

如果当前按钮是 ‘=’:
① 如果表达式为空什么也不做
② 如果最后是小数点补0
③ 把计算结果加入到表达式末尾并且存入结果记录并把表达式清空,更新最新历史记录

case Equal:
		//如果表达式为空不做操作
		if (str.length() == 0) {
			k = 0;
			return;
		}
		//如果最后是小数点补0
		if (str.right(1) == ".")str += "0";
		//string 和 QString的转换,把结果加在等号后面
		temp = str;
		result = calculator.calculate_expression(str.toStdString());
		str = QString::fromStdString(result);
		list.append(temp+ QString::fromStdString(" = ") +str);
		ui.lineEdit->setText(str);
		str = "";
		k = 0;
		return;

如果当前按钮是 ’ ←’:
① 删除表达式末尾的一个字符

case Back:
		str.chop(1);
		break;

如果当前按钮是 ‘CE’:
① 清空表达式

case Clear:
		str = "";
		break;

如果当前按钮是 ‘C’:
① 清空表达式及历史记录

case Empty:
		str = "";
		list.clear();
		break;

如果当前按钮是 ‘H’:
① 循环查看历史记录

case History:
		if (list.length() == 0)return;
		if (list.length() - 1 - k == -1)k=0;
		history = list.at(list.length()-1-k);
		ui.lineEdit->setText(history);
		k += 1;
		return;

最后记得更新编辑框结果

	//更新结果
	ui.lineEdit->setText(str);
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页