title: Calculator
date: 2022-09-04 11:10:12
tags: [Qt, 应用, C++]
typora-root-url: Calculator
使用Qt做一个简单计算器
能运行加减乘除、求余、求根运算。
环境
QtCreator
软件设计
采用简单的两层结构设计:UI层和逻辑层。软件比较简单,cpp文件只有5个。
代码编写
UI:MainWindow:
一个QTextBrowser,N个QPushButton。没有做样式。
点击按钮,输入响应数字、运算符,传递给逻辑层的CalculatorManger处理。处理完发送信号显示。
逻辑层:CalculatorManager
主要难点在于如何运算,这里使用后缀表达式的方法计算。
-
用户点击按钮输入的是中缀表达式,如:2+3,
-
在处理的时候给转成后缀表达式:2, 3, +,使用两个栈分别存数字和运算符。
- 这里需要注意的是,输入的运算符要和栈顶运算符比较:
- 栈顶优先级高,把数字栈栈顶两个元素pop()出来和预算符栈栈顶pop()进行运算,结果存入push()数字栈。再存入输入的运算符、数字。
- 输入的高,直接存。
- 这里需要注意的是,输入的运算符要和栈顶运算符比较:
-
用户输入“=”表示输入完成,将栈中元素依次pop()出,直到清空。
代码如下:
/** * @brief CalculatorManager::inputNumber:输入数字 * @param iNum */ void CalculatorManager::inputNumber(int iNum) { // 判断是不是小数 if (!m_bDecimal) m_dInput = m_dInput * 10 + iNum; else { m_iCount ++; int i = m_iCount; double dNum = static_cast<double>(iNum); while (i--) { dNum = dNum*1.0 / 10; } m_dInput = m_dInput + dNum; } m_strInput.append(QString::number(iNum)); emit sig_show(m_strInput); } /** * @brief CalculatorManager::inputPoint: 点击小数点 */ void CalculatorManager::inputPoint() { // 防止重复输入 if (m_bDecimal) { emit sig_show("INPUT ERROR!"); reset(); } else { m_bDecimal = true; m_strInput.append("."); emit sig_show(m_strInput); } } /** * @brief CalculatorManager::inputOperator: 输入运算符 * @param enOperator */ void CalculatorManager::inputOperator(EnOperator enOperator) { switch(enOperator) { case EN_PLUS: m_strInput.append(" + "); break; case EN_MINUS: m_strInput.append(" - "); break; case EN_TIMES: m_strInput.append(" x "); break; case EN_OVER: m_strInput.append(" ÷ "); break; case EN_MOD: m_strInput.append(" mod "); break; case EN_ROOT: m_strInput.append(" yroot "); break; case EN_NONE: default: break; } emit sig_show(m_strInput); m_stackNum.push(m_dInput); // 复位 m_dInput = 0; m_bDecimal = false; m_iCount = 0; if (true == m_stackOp.empty()) { m_stackOp.push(enOperator); } else { EnOperator enOpTop = m_stackOp.top(); int iPri = bOpPri(enOpTop, enOperator); if (iPri) { double num1 = m_stackNum.top(); m_stackNum.pop(); double num2 = m_stackNum.top(); m_stackNum.pop(); double dResult = 0.0; if(!compute(num1, num2, enOpTop, dResult)) { reset(); return ; } m_stackNum.push(dResult); m_stackOp.pop(); m_stackOp.push(enOperator); } else { m_stackOp.push(enOperator); } } } /** * @brief CalculatorManager::clickedEqual: 点击= */ void CalculatorManager::clickedEqual() { m_stackNum.push(m_dInput); m_dInput = 0; m_strInput = ""; while (!m_stackOp.empty()) { EnOperator enOp = m_stackOp.top(); m_stackOp.pop(); double num1 = m_stackNum.top(); m_stackNum.pop(); double num2 = m_stackNum.top(); m_stackNum.pop(); double dResult = 0.0; if(!compute(num1, num2, enOp, dResult)) { reset(); return ; } m_stackNum.push(dResult); } double dResult = m_stackNum.top(); emit sig_show(QString::number(dResult)); reset(); }
运行结果
代码地址:nanoahSR/QtCalculator: Make a simply calculator with Qt (github.com)
TODO
- 求余、求根的优先级好像还有些问题
- 括号
- 幂运算、对数,缺少很多功能
- 键盘输入
- 。。。