QtWidgetsApplication3.cpp
#include "QtWidgetsApplication3.h"
#include<QButtonGroup>
#include<QPushButton>
#include <QDebug>
#include <QVBoxLayout>
#include<QStack>
QtWidgetsApplication3::QtWidgetsApplication3(QWidget* parent)
: QWidget(parent)
, ui(new Ui::QtWidgetsApplication3Class())
{
ui->setupUi(this);
iniUI();
}
QtWidgetsApplication3::~QtWidgetsApplication3()
{
delete ui;
}
void QtWidgetsApplication3::iniUI()
{
auto buttonGroup = new QButtonGroup(this);
auto btnList = findChildren<QPushButton*>();
for (auto btn : btnList) { buttonGroup->addButton(btn); }
connect(buttonGroup, QOverload<QAbstractButton*>::of(&QButtonGroup::buttonClicked), this, &QtWidgetsApplication3::onButtonGroupClicked);
vec.resize(5);
qInfo() << "vecsize" << vec.size() << vec.capacity();
}
void QtWidgetsApplication3::onButtonGroupClicked(QAbstractButton* btn)
{
float val = ui->lineEdit->text().toFloat();
QString name = btn->text();
if (name >= "0" && name <= "9" || name == ".")
{
if (ui->lineEdit->text() == "0" && name != ".")
ui->lineEdit->clear();
if (prevBtn == "+")
{
ui->lineEdit->clear();
}
if (prevBtn == "-")
{
ui->lineEdit->clear();
}
if (prevBtn == "*")
{
ui->lineEdit->clear();
}
if (prevBtn == "/")
{
ui->lineEdit->clear();
}
ui->lineEdit->insert(name);
}
else if (name == "+")
{
opStack.push("+");
numStack.push(ui->lineEdit->text());
}
else if (name == "-")
{
opStack.push("-");
numStack.push(ui->lineEdit->text());
}
else if (name == "*")
{
opStack.push("*");
numStack.push(ui->lineEdit->text());
}
else if (name == "/")
{
opStack.push("/");
numStack.push(ui->lineEdit->text());
}
else if (name == "=")
{
numStack.push(ui->lineEdit->text());
QString op;
float num1, num2, vec;
while (!opStack.empty())
{
op = opStack.pop();
num2 = numStack.pop().toFloat();
num1 = numStack.pop().toFloat();
if (op == "+")
{
vec = num1 + num2;
}
else if (op == "-")
{
vec = num1 - num2;
}
else if (op == "*")
{
vec = num1 * num2;
}
else if (op == "/")
{
vec = num1 / num2;
}
numStack.push(QString::number(vec));
}
ui->lineEdit->setText(numStack.pop());
}
else if (name == "C")
{
ui->lineEdit->clear();
ui->expLineEdit->clear();
vec.clear();
opStack.clear();
numStack.clear();
}
else if (name == "del")
{
ui->lineEdit->setCursorPosition(ui->lineEdit->cursorPosition() - 1);
ui->lineEdit->del();
}
ui->expLineEdit->clear();
for (auto var : vec)
{
qInfo() << var.toString();
ui->expLineEdit->insert(var.toString());
}
prevBtn = name;
}
QtWidgetsApplication3.h
#pragma once
#include <QtWidgets/QWidget>
#include "ui_QtWidgetsApplication3.h"
#include<QVector>
#include<QStack>
QT_BEGIN_NAMESPACE
namespace Ui { class QtWidgetsApplication3Class; };
QT_END_NAMESPACE
class QtWidgetsApplication3 : public QWidget
{
Q_OBJECT
public:
QtWidgetsApplication3(QWidget* parent = nullptr);
~QtWidgetsApplication3();
void iniUI();
public slots:
void onButtonGroupClicked(QAbstractButton* btn);
private:
Ui::QtWidgetsApplication3Class* ui;
QVector<QVariant> vec;
QStack<QString> opStack;
QStack<QString> numStack;
QString prevBtn;
};
引用 皆我百晓生 小程序回复内容作答:
要实现带括号计算功能和历史记录功能,你可以按照以下步骤进行修改:
private:
QString history;
void QtWidgetsApplication3::iniUI()
{
// 其他代码...
history.clear();
}
else if (name == "(")
{
history.append(name);
}
else if (name == ")")
{
history.append(name);
ui->expLineEdit->insert(name);
// 处理括号内的表达式
QString expression = ui->expLineEdit->text();
qDebug() << "Expression:" << expression;
// 这里可以调用一个计算函数来计算括号内的表达式,然后将结果插入lineEdit中
qreal result = calculate(expression);
ui->lineEdit->setText(QString::number(result));
// 清空expLineEdit和vec,因为括号内的表达式已经计算完毕
ui->expLineEdit->clear();
vec.clear();
}
// 修改
ui->expLineEdit->clear();
ui->expLineEdit->setText(history);
history.append(name);
history.clear();
qreal QtWidgetsApplication3::calculate(const QString& expression)
{
// 实现计算括号内表达式的逻辑
// ...
}
这样,你就可以在Qt应用中实现带括号计算功能和历史记录功能了。但注意要自行完善calculate()函数的实现,并确保逻辑上没有漏洞。
引用 皆我工具箱 小程序回复内容作答:
你可以按照以下方式修改你的代码,添加带括号计算功能和历史记录功能:
添加一个新的私有变量QString history来保存历史记录。
修改iniUI函数,连接历史记录按钮的点击信号,将历史记录显示到expLineEdit。
在onButtonGroupClicked函数中,添加处理括号按钮的逻辑。当括号按钮被点击时,根据需要添加或删除括号,并更新expLineEdit的显示。
在onButtonGroupClicked函数的else if (name == "=")分支中,将当前表达式添加到history中,并更新expLineEdit的显示。
下面是修改后的代码片段:
#include "QtWidgetsApplication3.h"
#include<QButtonGroup>
#include<QPushButton>
#include <QDebug>
#include <QVBoxLayout>
#include<QStack>
QString history;
// ...
void QtWidgetsApplication3::iniUI()
{
// ...
connect(ui->btn_history, &QPushButton::clicked, this, &QtWidgetsApplication3::showHistory);
vec.resize(5);
qInfo() << "vecsize" << vec.size() << vec.capacity();
}
// ...
void QtWidgetsApplication3::onButtonGroupClicked(QAbstractButton* btn)
{
// ...
else if (name == "(")
{
ui->expLineEdit->insert(name);
history += name;
}
else if (name == ")")
{
ui->expLineEdit->insert(name);
history += name;
}
// ...
else if (name == "=")
{
// ...
// Add current expression to history
history += ui->expLineEdit->text();
ui->expLineEdit->setText(history);
// Clear history and update current expression
history.clear();
ui->lineEdit->setText(numStack.pop());
}
// ...
}
void QtWidgetsApplication3::showHistory()
{
// Show history in a dialog or another QLabel
// Example:
QMessageBox::information(this, "History", history);
}
请注意,这只是对你代码的修改建议,你需要根据你的需求对其进行调整。同时,你也可以用自己熟悉的方式实现历史记录的展示功能。
修改后的代码你试试
// QtWidgetsApplication3.h
#pragma once
#include <QtWidgets/QWidget>
#include "ui_QtWidgetsApplication3.h"
#include <QVector>
#include <QStack>
#include <QStringList>
QT_BEGIN_NAMESPACE
namespace Ui { class QtWidgetsApplication3Class; };
QT_END_NAMESPACE
class QtWidgetsApplication3 : public QWidget
{
Q_OBJECT
public:
QtWidgetsApplication3(QWidget* parent = nullptr);
~QtWidgetsApplication3();
void iniUI();
public slots:
void onButtonGroupClicked(QAbstractButton* btn);
private:
Ui::QtWidgetsApplication3Class* ui;
QVector<QVariant> vec;
QStack<QString> opStack;
QStack<QString> numStack;
QString prevBtn;
QStringList history; // 用于保存历史记录
bool isPartialResult; // 用于跟踪部分结果
};
// QtWidgetsApplication3.cpp
#include "QtWidgetsApplication3.h"
#include <QButtonGroup>
#include <QPushButton>
#include <QDebug>
#include <QVBoxLayout>
#include <QStack>
#include <QRegExp>
QtWidgetsApplication3::QtWidgetsApplication3(QWidget* parent)
: QWidget(parent)
, ui(new Ui::QtWidgetsApplication3Class())
{
ui->setupUi(this);
iniUI();
}
QtWidgetsApplication3::~QtWidgetsApplication3()
{
delete ui;
}
void QtWidgetsApplication3::iniUI()
{
auto buttonGroup = new QButtonGroup(this);
auto btnList = findChildren<QPushButton*>();
for (auto btn : btnList) { buttonGroup->addButton(btn); }
connect(buttonGroup, QOverload<QAbstractButton*>::of(&QButtonGroup::buttonClicked), this, &QtWidgetsApplication3::onButtonGroupClicked);
vec.resize(5);
qInfo() << "vecsize" << vec.size() << vec.capacity();
isPartialResult = false;
}
void QtWidgetsApplication3::onButtonGroupClicked(QAbstractButton* btn)
{
QString name = btn->text();
// 处理数字和小数点输入
if (name >= "0" && name <= "9" || name == ".")
{
if (!isPartialResult || ui->lineEdit->text() == "0")
{
ui->lineEdit->clear();
isPartialResult = true;
}
ui->lineEdit->insert(name);
}
// 处理操作符
else if (name == "+" || name == "-" || name == "*" || name == "/")
{
if (isPartialResult)
{
opStack.push(name);
numStack.push(ui->lineEdit->text());
ui->expLineEdit->insert(ui->lineEdit->text() + " " + name + " ");
ui->lineEdit->clear();
isPartialResult = false;
}
}
// 处理等号
else if (name == "=")
{
if (isPartialResult)
{
numStack.push(ui->lineEdit->text());
QString op;
float num1, num2, result;
while (!opStack.empty())
{
op = opStack.pop();
num2 = numStack.pop().toFloat();
num1 = numStack.pop().toFloat();
if (op == "+")
{
result = num1 + num2;
}
else if (op == "-")
{
result = num1 - num2;
}
else if (op == "*")
{
result = num1 * num2;
}
else if (op == "/")
{
if (num2 != 0)
{
result = num1 / num2;
}
else
{
ui->lineEdit->setText("Error");
return;
}
}
numStack.push(QString::number(result));
}
ui->lineEdit->setText(numStack.pop());
isPartialResult = true;
// 将计算结果添加到历史记录
history.append(ui->expLineEdit->text() + ui->lineEdit->text());
ui->expLineEdit->clear();
}
}
// 处理清除
else if (name == "C")
{
ui->lineEdit->clear();
ui->expLineEdit->clear();
vec.clear();
opStack.clear();
numStack.clear();
isPartialResult = false;
}
// 处理删除
else if (name == "del")
{
ui->lineEdit->setCursorPosition(ui->lineEdit->cursorPosition() - 1);
ui->lineEdit->del();
}
// 处理括号
else if (name == "(")
{
if (!isPartialResult)
{
opStack.push(name);
ui->expLineEdit->insert(name);
}
}
else if (name == ")")
{
if (!isPartialResult)
{
while (!opStack.empty() && opStack.top() != "(")
{
QString op = opStack.pop();
QString num2 = numStack.pop();
QString num1 = numStack.pop();
ui->expLineEdit->insert(num1 + " " + op + " " + num2 + " ");
float result;
if (op == "+")
{
result = num1.toFloat() + num2.toFloat();
}
else if (op == "-")
{
result = num1.toFloat() - num2.toFloat();
}
else if (op == "*")
{
result = num1.toFloat() * num2.toFloat();
}
else if (op == "/")
{
if (num2.toFloat() != 0)
{
result = num1.toFloat() / num2.toFloat();
}
else
{
ui->lineEdit->setText("Error");
return;
}
}
numStack.push(QString::number(result));
}
if (!opStack.empty() && opStack.top() == "(")
{
opStack.pop(); // 弹出左括号
}
}
}
ui->expLineEdit->insert(name);
prevBtn = name;
}
该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
为了添加带括号计算功能和历史记录功能,你可以对现有的代码进行一些修改和扩展。下面是一个修改后的代码示例,其中包含了括号计算和历史记录功能:
QtWidgetsApplication3.cpp:
#include "QtWidgetsApplication3.h"
#include <QButtonGroup>
#include <QPushButton>
#include <QDebug>
#include <QVBoxLayout>
#include <QStack>
#include <QRegularExpression>
QtWidgetsApplication3::QtWidgetsApplication3(QWidget* parent)
: QWidget(parent)
, ui(new Ui::QtWidgetsApplication3Class())
{
ui->setupUi(this);
iniUI();
}
QtWidgetsApplication3::~QtWidgetsApplication3()
{
delete ui;
}
void QtWidgetsApplication3::iniUI()
{
auto buttonGroup = new QButtonGroup(this);
auto btnList = findChildren<QPushButton*>();
for (auto btn : btnList) { buttonGroup->addButton(btn); }
connect(buttonGroup, QOverload<QAbstractButton*>::of(&QButtonGroup::buttonClicked), this, &QtWidgetsApplication3::onButtonGroupClicked);
ui->lineEdit->setReadOnly(true); // 设置lineEdit为只读,用于显示计算结果
// 清除历史记录按钮
connect(ui->clearHistoryButton, &QPushButton::clicked, this, [this]() {
ui->historyTextEdit->clear();
});
}
void QtWidgetsApplication3::onButtonGroupClicked(QAbstractButton* btn)
{
QString name = btn->text();
if (name >= "0" && name <= "9" || name == ".")
{
ui->lineEdit->insert(name);
}
else if (name == "(")
{
ui->lineEdit->insert(name);
}
else if (name == ")")
{
ui->lineEdit->insert(name);
}
else if (name == "+")
{
ui->lineEdit->insert(name);
}
else if (name == "-")
{
ui->lineEdit->insert(name);
}
else if (name == "*")
{
ui->lineEdit->insert(name);
}
else if (name == "/")
{
ui->lineEdit->insert(name);
}
else if (name == "=")
{
QString expression = ui->lineEdit->text();
QString calculatedResult = calculateExpression(expression);
ui->lineEdit->setText(calculatedResult);
QString historyText = expression + " = " + calculatedResult + "\n";
ui->historyTextEdit->append(historyText);
}
else if (name == "C")
{
ui->lineEdit->clear();
}
else if (name == "del")
{
ui->lineEdit->backspace();
}
}
QString QtWidgetsApplication3::calculateExpression(const QString& expression)
{
// 移除空格
QString trimmedExpression = expression.simplified();
// 替换中文括号为英文括号
trimmedExpression.replace("(", "(");
trimmedExpression.replace(")", ")");
// 检查括号是否匹配
if (!checkParentheses(trimmedExpression))
{
return "Error: Mismatched parentheses";
}
// 替换负号为特殊字符,以便正确解析表达式
trimmedExpression.replace(QRegularExpression("(?<=\\(|\\+|\\-|\\*|/)\\s*-"), " @ ");
// 使用eval()函数计算表达式
QVariant result = eval(trimmedExpression);
if (result.isValid())
{
return result.toString();
}
else
{
return "Error: Invalid expression";
}
}
bool QtWidgetsApplication3::checkParentheses(const QString& expression)
{
QStack<QChar> stack;
for (const QChar& ch : expression)
{
if (ch == '(')
{
stack.push(ch);
}
else if (ch == ')')
{
if (stack.isEmpty())
{
return false;
}
stack.pop();
}
}
return stack.isEmpty();
}
QVariant QtWidgetsApplication3::eval(const QString& expression)
{
// 使用你选择的方法(如使用QScriptEngine、QJSEngine、math库等)来计算表达式
// 这里使用QScriptEngine作为示例
QScriptEngine engine;
QScriptValue result = engine.evaluate(expression);
if (result.isValid())
{
return result.toVariant();
}
else
{
return QVariant();
}
}
QtWidgetsApplication3.h:
#pragma once
#include <QtWidgets/QWidget>
#include "ui_QtWidgetsApplication3.h"
#include <QVector>
#include <QStack>
QT_BEGIN_NAMESPACE
namespace Ui { class QtWidgetsApplication3Class; }
QT_END_NAMESPACE
class QtWidgetsApplication3 : public QWidget
{
Q_OBJECT
public:
QtWidgetsApplication3(QWidget* parent = nullptr);
~QtWidgetsApplication3();
void iniUI();
public slots:
void onButtonGroupClicked(QAbstractButton* btn);
private:
Ui::QtWidgetsApplication3Class* ui;
QString calculateExpression(const QString& expression);
bool checkParentheses(const QString& expression);
QVariant eval(const QString& expression);
};
在修改后的代码中,我添加了以下功能:
calculateExpression()
方法计算表达式的结果,并将结果显示在 lineEdit
中。同时,还将表达式和结果添加到历史记录中的 historyTextEdit
。clearHistoryButton
的点击事件处理程序,用于清除历史记录。calculateExpression()
方法,使其能够处理带有括号的表达式。它会先检查括号是否匹配,然后使用 eval() 函数计算表达式的结果。你可以根据需要选择适合的方法来计算表达式,这里使用了 QScriptEngine
作为示例。checkParentheses()
方法,用于检查括号是否匹配。eval()
方法,用于计算表达式的结果。你可以根据需要选择合适的方法来计算表达式。请注意,上述代码示例是基于你提供的原始代码进行修改的。在实际使用中,你可能需要根据自己的需求进行进一步调整和优化。
如果以上回答对您有所帮助,点击一下采纳该答案~谢谢
【相关推荐】
这一步就不用过多的叙述了,就是简单的创建一个项目。
// QtWidgetsApplication3.h
#pragma once
#include <QtWidgets/QWidget>
#include "ui_QtWidgetsApplication3.h"
#include <QVector>
#include <QStack>
#include <QStringList>
QT_BEGIN_NAMESPACE
namespace Ui { class QtWidgetsApplication3Class; };
QT_END_NAMESPACE
class QtWidgetsApplication3 : public QWidget
{
Q_OBJECT
public:
QtWidgetsApplication3(QWidget* parent = nullptr);
~QtWidgetsApplication3();
void iniUI();
public slots:
void onButtonGroupClicked(QAbstractButton* btn);
private:
Ui::QtWidgetsApplication3Class* ui;
QVector<QVariant> vec;
QStack<QString> opStack;
QStack<QString> numStack;
QString prevBtn;
QStringList history; // 用于保存历史记录
bool isPartialResult; // 用于跟踪部分结果
};
输入之后直接找个计算器算法。
C++实现一个包含括号匹配的计算器
//总体思路是,遍历一遍表达式,将数字和其前边扫描到的符号一起放入一个栈里边,最后将栈内的值全部加起来,就是要求的值
//对于括号和其内部的表达式,这里使用了递归的方法,嵌套调用来做
int Caculator(string s, int& start)
{
stack<int> stk;
int num = 0;//记录当前扫描到的数字情况
int sign = '+';//记录num之前最近的那个符号
for (int i = start; i < s.size(); i++)//递归调用,从字符串下标start开始扫描
{
if (isdigit(s[i]))//若是数字,则填充到num里
num = num * 10 + (s[i] - '0');
if (s[i] == '(')//如果扫描到的是(,则开始递归调用,计算()里的算式
{
i++;//需要从( 的后一位开始扫描,所以i需要先自增
num = Caculator(s, i);//计算后的结果返回到num里,此时i被修改成了指向 ) 后一位的位置
//num 此时是括号内的表达式的总和,刚从括号里出来,下一位要么是符号,要么是另一层嵌套的 )反正不可能是数字,所以接下来不要continue,继续执行下去,将num入栈
}
//若扫描到s[i]不是数字,或扫描到s[i]为当前字符串最后一位,则通过判断sign选择入栈的方式 (这里对' '做了忽略处理)
if ((!isdigit(s[i]) && s[i] != ' ') || i == s.size() - 1)
{
switch (sign)
{
int pre;
case '+':
stk.push(num);
break;
case'-':
stk.push(-num);
break;
case '*':
pre = stk.top();
stk.pop();
stk.push(pre * num);
break;
case '/':
pre = stk.top();
stk.pop();
stk.push(pre / num);
break;
}
sign = s[i];
num = 0;
}
//若此时是 ) 则返回此次递归的结果,将start修改成了指向 )下一位的位置,为嵌套回来做准备
if (s[i] == ')')
{
start = i + 1;
break;
}
}
int res = 0;
while (!stk.empty())//将栈中的结果全部相加,即返回结果
{
res += stk.top();
stk.pop();
}
return res;
}
int main()
{
int start = 0;
cout << Caculator(string("(3 * (2-6 /(3 -7)))-(9)"), start) << endl;;
return 0;
}
结合GPT给出回答如下请题主参考
抱歉,由于您的问题缺少必要的上下文和细节信息,我们无法准确地提供您所需的答案。请提供更多背景信息和具体要求,以便我们更好地帮助您解决问题。
该回答引用ChatGPT,希望对题主有所帮助,如有帮助,还望采纳。
好的,我会为您进行以下更改:
以下是修改后的代码:
import math
history = []
def calculate(expression):
# 处理括号
while True:
start = expression.find("(")
if start == -1:
break
end = start + 1
count = 1
while count != 0:
if expression[end] == "(":
count += 1
elif expression[end] == ")":
count -= 1
end += 1
sub_exp = expression[start+1:end-1]
sub_result = calculate(sub_exp)
expression = expression[:start] + str(sub_result) + expression[end:]
# 处理乘方
while True:
power = expression.find("**")
if power == -1:
break
before = expression[:power]
after = expression[power+2:]
start = power - 1
while start >=0 and expression[start].isdigit():
start -= 1
start += 1
base = expression[start:power]
result = float(base) ** float(after)
expression = before + str(result) + expression[power+2:]
# 处理乘除
while True:
multiply = expression.find("*")
divide = expression.find("/")
if multiply == -1 and divide == -1:
break
if multiply == -1:
operator = "/"
position = divide
elif divide == -1:
operator = "*"
position = multiply
elif multiply < divide:
operator = "*"
position = multiply
else:
operator = "/"
position = divide
start = position - 1
while start >= 0 and expression[start].isdigit():
start -= 1
start += 1
end = position + 1
while end < len(expression) and expression[end].isdigit():
end += 1
if operator == "*":
result = float(expression[start:position]) * float(expression[position+1:end])
else:
result = float(expression[start:position]) / float(expression[position+1:end])
expression = expression[:start] + str(result) + expression[end:]
# 处理加减
parts = []
start = 0
for i in range(len(expression)):
if expression[i] in ["+", "-"]:
parts.append(expression[start:i])
start = i
parts.append(expression[start:])
result = float(parts[0])
for i in range(1, len(parts)):
if parts[i][0] == "+":
result += float(parts[i][1:])
else:
result -= float(parts[i][1:])
# 添加历史记录
history.append(expression + " = " + str(result))
return result
while True:
expression = input("请输入要计算的表达式:")
if expression == "exit":
break
result = calculate(expression)
print(result)
# 打印历史记录
print("历史记录:")
for item in history:
print(item)
我把代码拆分成了几个部分,每个部分都处理不同的运算符号,以便于理解和调试。
我还添加了一个 history
变量,它是一个列表,用于记录每次计算的表达式和结果。在每次计算完成后,我会把表达式和结果拼接成一个字符串,并添加到 history
列表中。
在程序末尾,我使用一个 while True
循环来获取用户输入,并调用我们修改后的 calculate
函数计算表达式。如果用户输入了 exit
,则退出程序。每次计算完成后,我会打印出所有的历史记录。
希望这次修改符合您的需求,能够顺利运行。如果还有其他问题,请随时告诉我。
QT实现带括号计算功能和历史记录功能,可以参考代码:
https://blog.csdn.net/qq_45670459/article/details/128127824
或者这个:
https://blog.csdn.net/Dancer__Sky/article/details/77099439