代码
widget.h
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QGridLayout>
#include <QSizePolicy>
#include <QLineEdit>
#include <QDebug>
#include <QtGlobal>
#include <QStack>
#include <cmath>
class Widget : public QWidget
{
Q_OBJECT
QLineEdit *edit = new QLineEdit();
bool m_clearOnNextInput; // 新增:标志位,下次输入是否清除内容
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void onNumberButtonClicked(const QString &number);
void onEqualClicked();
};
#endif // WIDGET_H
widget.cpp
cpp
#include "widget.h"
#include <vector>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
m_clearOnNextInput = false; // 初始状态:不清除
QGridLayout *layout = new QGridLayout();
//按钮
QPushButton* pqb1= new QPushButton("1");
QPushButton* pqb2= new QPushButton("2");
QPushButton* pqb3= new QPushButton("3");
QPushButton* pqb4= new QPushButton("4");
QPushButton* pqb5= new QPushButton("5");
QPushButton* pqb6= new QPushButton("6");
QPushButton* pqb7= new QPushButton("7");
QPushButton* pqb8= new QPushButton("8");
QPushButton* pqb9= new QPushButton("9");
QPushButton* pqb0= new QPushButton("0");
QPushButton* pqb10= new QPushButton("+");
QPushButton* pqb11= new QPushButton("-");
QPushButton* pqb12= new QPushButton("*");
QPushButton* pqb13= new QPushButton("/");
QPushButton* pqb14= new QPushButton(".");
QPushButton* pqb15= new QPushButton("=");
pqb1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb4->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb5->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb6->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb7->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb8->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb9->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb10->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb11->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb12->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb13->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb14->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb15->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pqb0->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layout->addWidget(pqb0,3,0);
layout->addWidget(pqb1,2,0);
layout->addWidget(pqb2,2,1);
layout->addWidget(pqb3,2,2);
layout->addWidget(pqb4,1,0);
layout->addWidget(pqb5,1,1);
layout->addWidget(pqb6,1,2);
layout->addWidget(pqb7,0,0);
layout->addWidget(pqb8,0,1);
layout->addWidget(pqb9,0,2);
layout->addWidget(pqb10,3,2);
layout->addWidget(pqb11,0,3);
layout->addWidget(pqb12,1,3);
layout->addWidget(pqb13,2,3);
layout->addWidget(pqb14,3,1);
layout->addWidget(pqb15,3,3);
edit->show();
edit->setMaximumHeight(150);
QGridLayout *layout1 = new QGridLayout(this);
edit->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
edit->setReadOnly(true); // 禁止手动输入
layout1->addLayout(layout,1,0,4,4);
layout1->addWidget(edit,0,0,1,4);
std::vector<QPushButton*> arr = {pqb0,pqb1,pqb2,pqb3,pqb4,pqb5,pqb6,pqb7,pqb8,
pqb9,pqb10,pqb11,pqb12,pqb13,pqb14};
for(auto &ele : arr){
connect(ele, &QPushButton::clicked, this, [this,ele](){
this->onNumberButtonClicked(ele->text());});
}
connect(pqb15, &QPushButton::clicked, this, &Widget::onEqualClicked);
}
Widget::~Widget()
{
}
// 槽函数实现:追加数字到显示框
void Widget::onNumberButtonClicked(const QString &number) {
if (m_clearOnNextInput) {
// 如果需要清除,则先清空显示框,再输入新数字
edit->setText(number);
m_clearOnNextInput = false; // 重置标志位(下次输入恢复追加)
} else {
// 不需要清除,则直接追加数字
edit->setText(edit->text() + number);
}
}
//等号计算
QString calculateSimpleExpression(const QString &expression);
void Widget::onEqualClicked() {
QString expr = edit->text(); // 获取QLineEdit中的表达式
QString result = calculateSimpleExpression(expr);
edit->setText(result); // 显示结果
m_clearOnNextInput = true;
}
// 辅助函数:判断是否为运算符(仅支持 +-*/)
bool isOperator(const QChar &c) {
return c == '+' || c == '-' || c == '*' || c == '/';
}
// 辅助函数:获取运算符优先级(乘除 > 加减)
int getPriority(const QChar &op) {
if (op == '+' || op == '-') return 1; // 优先级低
if (op == '*' || op == '/') return 2; // 优先级高
return 0;
}
// 步骤1:中缀表达式转后缀表达式(无括号版本)
QVector<QString> infixToPostfix(const QString &expression) {
QVector<QString> postfix; // 存储后缀表达式
QStack<QChar> opStack; // 运算符栈
QString numBuffer; // 缓存数字(支持多位数和小数)
for (int i = 0; i < expression.size(); ++i) {
QChar c = expression[i];
// 跳过空格
if (c.isSpace()) continue;
// 处理数字或小数点
if (c.isDigit() || c == '.') {
numBuffer += c;
}
// 处理运算符
else if (isOperator(c)) {
// 先将缓存的数字加入后缀表达式
if (numBuffer.isEmpty()) {
return {}; // 连续运算符(如"1++2"),返回错误
}
postfix.append(numBuffer);
numBuffer.clear();
// 弹出栈中优先级 >= 当前运算符的运算符
while (!opStack.isEmpty() && getPriority(opStack.top()) >= getPriority(c)) {
postfix.append(opStack.top());
opStack.pop();
}
opStack.push(c); // 当前运算符入栈
}
// 非法字符(非数字、非运算符、非小数点)
else {
return {}; // 含非法字符,返回错误
}
}
// 处理最后一个数字
if (numBuffer.isEmpty()) {
return {}; // 表达式以运算符结尾(如"1+"),返回错误
}
postfix.append(numBuffer);
// 弹出栈中剩余运算符
while (!opStack.isEmpty()) {
postfix.append(opStack.top());
opStack.pop();
}
return postfix;
}
// 步骤2:计算后缀表达式结果
QString calculatePostfix(const QVector<QString> &postfix) {
if (postfix.isEmpty()) return "错误";
QStack<double> numStack; // 数字栈
for (const QString &token : postfix) {
// 如果是数字,入栈
if (!isOperator(token[0]) || (token.size() > 1 && token[0] == '-')) {
bool ok;
double num = token.toDouble(&ok);
if (!ok) return "错误"; // 数字格式错误(如多小数点)
numStack.push(num);
}
// 如果是运算符,计算
else {
if (numStack.size() < 2) return "错误"; // 操作数不足
double b = numStack.pop(); // 注意顺序:后弹出的是第一个操作数
double a = numStack.pop();
double result = 0;
if (token == "+") {
result = a + b;
} else if (token == "-") {
result = a - b;
} else if (token == "*") {
result = a * b;
} else if (token == "/") {
if (qFuzzyCompare(b, 0.0)) return "错误"; // 除零错误
result = a / b;
}
numStack.push(result);
}
}
// 最终栈中应只有一个结果
if (numStack.size() != 1) return "错误";
// 优化显示:整数去掉".0"
double finalResult = numStack.pop();
if (finalResult == floor(finalResult)) {
return QString::number((long long)finalResult); // 整数显示
} else {
return QString::number(finalResult); // 小数显示
}
}
// 对外接口:计算无括号的表达式
QString calculateSimpleExpression(const QString &expression) {
// 空表达式处理
if (expression.trimmed().isEmpty()) return "";
// 中缀转后缀
QVector<QString> postfix = infixToPostfix(expression);
if (postfix.isEmpty()) return "错误"; // 转换失败(格式错误)
// 计算结果
return calculatePostfix(postfix);
}
测试结果
