QT5-msvc2015 实例之计算器

这篇博客介绍了如何使用QT5和msvc2015编译环境来创建两个不同类型的计算器程序。一个是基础版,仅支持整数的加减乘除操作;另一个则更复杂,能够处理小数和括号,涉及到了中缀表达式的转换。
摘要由CSDN通过智能技术生成

QT的计算器编写还是有很多资料的,这里给的程序包含了两种计算器。

一种是功能简单的计算器,只能实现整数 +-*/,适合刚学习的小伙伴。

另一种是包含小数,括号的计算器,需要用到中缀的转换。

calculator.h

#ifndef CALCULATOR_H
#define CALCULATOR_H

#include <QDialog>
#include<qlineedit.h>
#include<qpushbutton.h>
#include<QHBoxLayout>
#include<QVBoxLayout>

class Calculator : public QDialog
{
    Q_OBJECT

public:
    Calculator(QWidget *parent = 0);
    ~Calculator();
	int num1, num2;
	double result;
	QString str;
	char opera;
	QLineEdit *lineEdit;

	QPushButton *button_0;
	QPushButton *button_1;
	QPushButton *button_2;
	QPushButton *button_3;
	QPushButton *button_4;
	QPushButton *button_5;
	QPushButton *button_6;
	QPushButton *button_7;
	QPushButton *button_8;
	QPushButton *button_9;

	QPushButton *button_add;
	QPushButton *button_sub;
	QPushButton *button_mul;
	QPushButton *button_div;

	QPushButton *button_dot;
	QPushButton *button_bra;
	QPushButton *button_ket;

	QPushButton *button_eql;
	//QPushButton *button_ce;
	private slots:
	void button_0_clicked();
	void button_1_clicked();
	void button_2_clicked();
	void button_3_clicked();
	void button_4_clicked();
	void button_5_clicked();
	void button_6_clicked();
	void button_7_clicked();
	void button_8_clicked();
	void button_9_clicked();

	void button_add_clicked();
	void button_sub_clicked();
	void button_mul_clicked();
	void button_div_clicked();

	void button_eql_clicked();
	void button_bra_clicked();
	void button_ket_clicked();
	void button_dot_clicked();
};

#endif // CALCULATOR_H

calculator.cpp

#include "calculator.h"
#include<expression.h>
#include<iostream>
#include<QString>

Calculator::Calculator(QWidget *parent)
    : QDialog(parent)
{
	num1 = 0;
	num2 = 0;
	result = 0;
	str = "";

	//初始化控件
	lineEdit = new QLineEdit("0");

	button_0 = new QPushButton("0");
	button_1 = new QPushButton("1");
	button_2 = new QPushButton("2");
	button_3 = new QPushButton("3");
	button_4 = new QPushButton("4");
	button_5 = new QPushButton("5");
	button_6 = new QPushButton("6");
	button_7 = new QPushButton("7");
	button_8 = new QPushButton("8");
	button_9 = new QPushButton("9");

	button_add = new QPushButton("+");
	button_sub = new QPushButton("-");
	button_mul = new QPushButton("*");
	button_div = new QPushButton("/");

	button_eql = new QPushButton("=");
	button_bra = new QPushButton("(");
	button_ket = new QPushButton(")");
	button_dot = new QPushButton(".");

	button_eql->setStyleSheet("background-color: rgb(255, 80,20);");//132, 139
	 

	//布局控件
	/*先将水平控件布局好,再将水平布局嵌入垂直布局;
	//每个水平布局是垂直布局的控件。
	QHBoxLayout *Hl1 = new QHBoxLayout;
	QHBoxLayout *Hl2 = new QHBoxLayout;
	QHBoxLayout *Hl3 = new QHBoxLayout;
	QHBoxLayout *Hl4 = new QHBoxLayout;
	QHBoxLayout *Hl5 = new QHBoxLayout;
	Hl1->addWidget(lineEdit);
	Hl1->addWidget(button_ce);
	Hl2->addWidget(button_1);
	Hl2->addWidget(button_2);
	Hl2->addWidget(button_3);
	Hl2->addWidget(button_add);
	Hl3->addWidget(button_4);
	Hl3->addWidget(button_5);
	Hl3->addWidget(button_6);
	Hl3->addWidget(button_sub);
	Hl4->addWidget(button_7);
	Hl4->addWidget(button_8);
	Hl4->addWidget(button_9);
	Hl4->addWidget(button_mul);
	Hl5->addWidget(button__);
	Hl5->addWidget(button_0);
	Hl5->addWidget(button_eql);
	Hl5->addWidget(button_div);//addWidget,添加小部件

	QVBoxLayout *V1 = new QVBoxLayout;
	V1->addLayout(Hl1);
	V1->addLayout(Hl2);
	V1->addLayout(Hl3);
	V1->addLayout(Hl4);
	V1->addLayout(Hl5);		//addLayout,添加布局
	
	setLayout(V1);
	*/

	//QGridLayout格栅布局
	
	QGridLayout *H = new QGridLayout();
	H->addWidget(lineEdit, 0, 0, 1, 2);
	H->addWidget(button_add, 0, 3, 1, 1);
	H->addWidget(button_0, 0, 2, 1, 1);

	H->addWidget(button_1, 1, 0, 1, 1);
	H->addWidget(button_2, 1, 1, 1, 1);
	H->addWidget(button_3, 1, 2, 1, 1);
	H->addWidget(button_sub, 1, 3, 1, 1);

	H->addWidget(button_4, 2, 0, 1, 1);
	H->addWidget(button_5, 2, 1, 1, 1);
	H->addWidget(button_6, 2, 2, 1, 1);
	H->addWidget(button_mul, 2, 3, 1, 1);

	H->addWidget(button_7, 3, 0, 1, 1);
	H->addWidget(button_8, 3, 1, 1, 1);
	H->addWidget(button_9, 3, 2, 1, 1);
	H->addWidget(button_div, 3, 3, 1, 1);

	H->addWidget(button_bra, 4, 0, 1, 1);
	H->addWidget(button_ket, 4, 1, 1, 1);
	H->addWidget(button_dot, 4, 2, 1, 1);
	H->addWidget(button_eql, 4, 3, 1, 1);

	H->setHorizontalSpacing(10);
	H->setVerticalSpacing(10);
	H->setContentsMargins(10, 10, 10, 10);

	setLayout(H);
	

	//信号与槽函数连接
	connect(button_0, SIGNAL(clicked()), this, SLOT(button_0_clicked()));
	connect(button_1, SIGNAL(clicked()), this, SLOT(button_1_clicked()));
	connect(button_2, SIGNAL(clicked()), this, SLOT(button_2_clicked()));
	connect(button_3, SIGNAL(clicked()), this, SLOT(button_3_clicked()));
	connect(button_4, SIGNAL(clicked()), this, SLOT(button_4_clicked()));
	connect(button_5, SIGNAL(clicked()), this, SLOT(button_5_clicked()));
	connect(button_6, SIGNAL(clicked()), this, SLOT(button_6_clicked()));
	connect(button_7, SIGNAL(clicked()), this, SLOT(button_7_clicked()));
	connect(button_8, SIGNAL(clicked()), this, SLOT(button_8_clicked()));
	connect(button_9, SIGNAL(clicked()), this, SLOT(button_9_clicked()));
	connect(button_add, SIGNAL(clicked()), this, SLOT(button_add_clicked()));
	connect(button_sub, SIGNAL(clicked()), this, SLOT(button_sub_clicked()));
	connect(button_mul, SIGNAL(clicked()), this, SLOT(button_mul_clicked()));
	connect(button_div, SIGNAL(clicked()), this, SLOT(button_div_clicked()));
	connect(button_eql, SIGNAL(clicked()), this, SLOT(button_eql_clicked()));
	connect(button_bra, SIGNAL(clicked()), this, SLOT(button_bra_clicked()));
	connect(button_ket, SIGNAL(clicked()), this, SLOT(button_ket_clicked()));
	connect(button_dot, SIGNAL(clicked()), this, SLOT(button_dot_clicked()));

}

Calculator::~Calculator()
{

}

void Calculator::button_0_clicked()
{
	str += "0";
	lineEdit->setText(str);

}

void Calculator::button_1_clicked()
{
	str += "1";
	lineEdit->setText(str);

}

void Calculator::button_2_clicked()
{
	str += "2";
	lineEdit->setText(str);

}

void Calculator::button_3_clicked()
{
	str += "3";
	lineEdit->setText(str);

}

void Calculator::button_4_clicked()
{
	str += "4";
	lineEdit->setText(str);

}

void Calculator::button_5_clicked()
{
	str += "5";
	lineEdit->setText(str);

}

void Calculator::button_6_clicked()
{
	str += "6";
	lineEdit->setText(str);

}

void Calculator::button_7_clicked()
{
	str += "7";
	lineEdit->setText(str);

}

void Calculator::button_8_clicked()
{
	str += "8";
	lineEdit->setText(str);

}

void Calculator::button_9_clicked()
{
	str += "9";
	lineEdit->setText(str);

}

void Calculator::button_dot_clicked()
{
	str += ".";
	lineEdit->setText(str);

}

void Calculator::button_add_clicked()
{
	str += "+";
	lineEdit->setText(str);
	
	opera = '+';

}

void Calculator::button_sub_clicked()
{
	str += "-";
	lineEdit->setText(str);

	opera = '-';

}

void Calculator::button_mul_clicked()
{
	str += "*";
	lineEdit->setText(str);

	opera = '*';

}

void Calculator::button_div_clicked()
{
	str += "/";
	lineEdit->setText(str);

	opera = '/';

}

void Calculator::button_bra_clicked()
{
	str += "(";
	lineEdit->setText(str);
}

void Calculator::button_ket_clicked()
{
	str += ")";
	lineEdit->setText(str);
}

void Calculator::button_eql_clicked()
{
	//简单计算器
	//str += "=";
	/*int pos = 0;
	//int postail= str.indexOf('=');
	QString str1, str2;
	switch (opera)
	{
	case '+':pos = str.indexOf('+'); break;
	case '-':pos = str.indexOf('-'); break;
	case '*':pos = str.indexOf('*'); break;
	case '/':pos = str.indexOf('/'); break;
	}
	//pos = str.lastIndexOf('+');
	str1 = str.mid(0, pos);
	str2 = str.mid(pos + 1);
	
	bool ok;
	num1 = str1.toInt(&ok);
	num2 = str2.toInt(&ok);

	switch (opera) {
	case '+':result = num1 + num2; break;
	case '-':result = num1 - num2; break;
	case '*':result = num1 * num2; break;
	case '/':result = (double) num1 / num2; break;
	}
	str += "=";
	str += QString::number(result);

	lineEdit->setText(str);
	num1 = 0;
	num2 = 0;
	str = "";
	*/

	vector<string> tmp;
	string sstr = str.toStdString();//QString to string
	tmp = preExpression(sstr);
	int len1 = tmp.size();
	stack<string> st;
	for (int i = len1 - 1; i >= 0; i--)
	{
		st.push(tmp[i]);
	}

	result = calculatenew(st);
	str += "=";
	str += QString::number(result);
	lineEdit->setText(str);
	str = "";
}

expression.cpp 中缀转前缀

#include<expression.h>

int getPriority(char ch)//操作符优先级
{
	int prio = 0;
	if (ch == '*' || ch == '/')
		prio = 2;
	else if (ch == '+' || ch == '-')
		prio = 1;
	else if (ch == ')')
		prio = 0;
	return prio;
}
//判断字符是否是数字
// if(isdigit(str[j]))
//isalnum() 用来判断一个字符是否为英文字母或数字,相当于 isalpha(c) || isdigit(c)
//isalpha() 用来判断一个字符是否是英文字母,相当于 isupper(c)||islower(c)大小写
int getNum(string str)
{
	int len = str.size();
	int mark = 0;
	for (int i = len - 1; i >= 0; i--)
	{
		if (isdigit(str[i])) continue;
		if (str[i] == '.') continue;
		if (!isdigit(str[i])) { mark = i + 1; break; }
	}
	return mark;
}

string chtos(char c)
{
	char tmp[1];
	tmp[0] = c;
	string result(tmp, 1);
	return result;
}

string dtos(double d) {//double to string
	ostringstream os;
	if (os << d) return os.str();
	else return "invalid conversion";
}


vector<string> preExpression(string str)
{
	vector<string> number;
	stack<char> notation;
	int len = str.size();
	int pos;
	for (int i = len - 1; i >= 0; i--)
	{
		if (isdigit(str[i]))
		{
			pos = getNum(str.substr(0, i + 1));
			number.push_back(str.substr(pos, i - pos + 1));
			i = pos;
		}
		else {
			if (notation.empty() || str[i] == ')') notation.push(str[i]);
			else if (str[i] == '(')
			{
				while (notation.top() != ')')
				{
					number.push_back(chtos(notation.top()));
					notation.pop();
				}
				notation.pop();
			}
			else if (!notation.empty() && getPriority(str[i]) >= getPriority(notation.top()))
			{
				notation.push(str[i]);
			}
			else if (!notation.empty() && getPriority(str[i])<getPriority(notation.top()))
			{
				number.push_back(chtos(notation.top()));
				notation.pop();
				notation.push(str[i]);
			}
		}
	}

	while (!notation.empty())
	{
		number.push_back(chtos(notation.top()));
		notation.pop();
	}
	return number;
}


double calculatenew(stack<string> st)
{
	stack <string> operation;
	double lope;
	double rope;
	double result;
	while (!st.empty())
	{

		string tmp = st.top();
		if (isdigit(*tmp.begin()))
		{
			operation.push(st.top());
			st.pop();
		}
		else
		{
			string ch = st.top();

			if (ch == "+")
			{
				lope = atof(operation.top().c_str());
				operation.pop();
				rope = atof(operation.top().c_str());
				operation.pop();
				result = lope + rope;
				operation.push(dtos(result));
			}
			if (ch == "-")
			{
				lope = atof(operation.top().c_str());
				operation.pop();
				rope = atof(operation.top().c_str());
				result = lope - rope;
				operation.pop();
				operation.push(dtos(result));
			}
			if (ch == "*")
			{
				lope = atof(operation.top().c_str());
				operation.pop();
				rope = atof(operation.top().c_str());
				result = lope*rope;
				operation.pop();
				operation.push(dtos(result));
			}
			if (ch == "/")
			{
				lope = atof(operation.top().c_str());
				operation.pop();
				rope = atof(operation.top().c_str());
				result = lope / rope;
				operation.pop();
				operation.push(dtos(result));
			}
			st.pop();
		}
	}
	return result;
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值