天天看点

Qt入门练习项目——计算器

第一次尝试使用Qt进行开发。在此之前还尚未接触到过这一类的ui设计,所以通过写计算器的方式对Qt进行熟悉。

先上结果图
           
Qt入门练习项目——计算器
Qt入门练习项目——计算器

   仅仅实现了 加减乘除和不嵌套使用的括号 以及小数 后退 清空功能

首先是需求分析:

  1. 要实现那些功能
  2. 如何表达当前的输入情况
  3. 如何实现权重问题和括号的位置识别

以下是功能的实现构思及代码

  • 上界面也是表达式界面,是执行操作的数字和符号的储存地和用户输入的显示处。
  • 下界面显示用户当前输入的界面,每当输入新输入的数据与该界面已经显示的数据不同时将重置显示。
  • 如用户输入了123,此时下界面显示为123,当在输入+时 下界面将清空并显示+,再此输入数字或括号时 下界面会再次清空显示当前输入。

                      代码如下

    方法类:

void Calculate::appendData(QString str)
{
	if (str == "+" || str == "-" || str == "*" || str == "/" || str == "(" || str == ")" )
	{
		if (str=="(")
		{
			m_datas.append(str);
			m_currDatas = str;
			m_expression += str;
		}
		else if (str==")")
		{
			m_datas.append(m_currDatas);
			m_datas.append(str);
			m_currDatas = str;
			m_expression += str;
		}
		else if (m_currDatas=="(")
		{
			m_datas.append(str);
			m_currDatas = str;
			m_expression += str;
		}
		 else if(m_currDatas==")")
		{
			m_datas.append(str);
			m_expression += str;
			m_currDatas = str;
		}
		 else
		 {
			 m_datas.append(m_currDatas);
			 m_datas.append(str);
			 m_currDatas = str;
			 m_expression += str;
		 }
	}
	else if (str=="=")
	{
		if (m_currDatas != ")")
		{
			m_datas.append(m_currDatas);
		}	
	}
	else
	{
		if (m_currDatas=="(")
		{
			m_currDatas = "";
			m_currDatas += str;
			m_expression += str;
		}
		else
		{
			m_currDatas += str;
			m_expression += str;
		}
	}
}
           

写的很长但其实是把简单问题复杂化了,写完后发现 写一个函数来判定下界面为空就输出表达式的上一个字符串,这样可以节省三分之二的代码。所以这是一长串废代码。

窗口:

//数字
void MainWindow::on_all_click()
{
    QPushButton *p = static_cast<QPushButton *>(sender());
    calc->currDataClear();
    QString str = p->text();
    calc->appendData(str);
    ui->le_1->setText(calc->getExpression());
    ui->le_2->setText(calc->getCurrData());
}
void MainWindow::on_leftDrackets_click()
{
	QString str = "(";
	calc->appendData(str);
	ui->le_1->setText(calc->getExpression());
	ui->le_2->setText(calc->getCurrData());


}
void MainWindow::on_rightDrackets_click()
{
	QString str = ")";
	calc->appendData(str);
	ui->le_1->setText(calc->getExpression());
	ui->le_2->setText(calc->getCurrData());
}
//后退
void MainWindow::on_zuo_click()
{
    calc->retreat();
    ui->le_2->setText(calc->getCurrData());
    ui->le_1->setText(calc->getExpression());

}
//操作符
void MainWindow::on_deng_click()
{
    QString str = "=";
    calc->appendData(str);
    calc->calculateResult();
    ui->le_2->setText(calc->outResult());
    calc->clearAll();
}
void MainWindow::on_cheng_click()
{	
    QString str = "*";
    calc->appendData(str);
    ui->le_1->setText(calc->getExpression());
    ui->le_2->setText(calc->getCurrData());

}
void MainWindow::on_chu_click()
{
    QString str = "/";
    calc->appendData(str);
    ui->le_1->setText(calc->getExpression());
    ui->le_2->setText(calc->getCurrData());

}
void MainWindow::on_jia_click()
{
    QString str = "+";
    calc->appendData(str);
    ui->le_1->setText(calc->getExpression());
    ui->le_2->setText(calc->getCurrData());

}
void MainWindow::on_jian_click()
{
    QString str = "-";
    calc->appendData(str);
    ui->le_1->setText(calc->getExpression());
    ui->le_2->setText(calc->getCurrData());

}
void MainWindow::on_C_click()
{
    calc->clearAll();
    ui->le_1->setText(calc->getExpression());
    ui->le_2->setText(calc->getCurrData());
}
           

窗口上的输入 m_datas 是一个Qlist 的QString。

数据的录入完成后剩下的就是操作部分

   数据操作的时候存在着权重问题可以将加减、乘除、括号分开操作顺序如下

  1. 处理括号   括号的优先级是最高,也是里面最难处理的。先将m_datas中的数据遍历分别存入  QList m_Numbers

    (数字)和 QList m_Symbols(符号)中;

      当遍历到左括号且下一位不是右括号时 将m_datas.at(i+1)位加入m_Symbols中,将m_datas.at(i)加入m_Numbers中 ,同时删除m_datas.at(i),当遍历到右括号时调用priorityCalculate();(加法);

    当遍历完成后m_datas中括号内的数据都被操作完成此时i指在左括号的位置 。

for (int i = 0; i < m_datas.length();i++)
	{
		if (m_datas.at(i) == "(")
		{
			i++;
			while (m_datas.at(i) != ")")
			{
				if (m_datas.at(i + 1) != ")")
				{
					m_Symbols.append(m_datas.at(i + 1));
				}
				m_Numbers.append(m_datas.at(i));
				m_datas.removeAt(i);
				if (m_datas.at(i) != ")")
				{
					m_datas.removeAt(i);
				}
			}
			m_datas.removeAt(i);
			priorityCalculate();
			m_datas[i - 1] = m_result.at(0);
			m_result.clear();
			m_Numbers.clear();
			m_Symbols.clear();
		}
	}
           

priorityCalculate()函数调用完成后将结果赋值给m_datas.at(i),此时的m_datas中就只有 + - * / 这四个符号 在进行遍历将数据与字符分开调用priorityCalculate()函数即可;

2.       乘除的处理:priorityCalculate()函数如下:

void Calculate::priorityCalculate()
{

	int n = 0;
	while (n < m_Symbols.length())
	{
		if (m_Symbols.at(n) == "*" || m_Symbols.at(n) == "/")
		{
			double x = 0;
			double y = 0;
			x = m_Numbers.at(n).toDouble();
			y = m_Numbers.at(n + 1).toDouble();
			if (m_Symbols.at(n) == "*")
			{
				double result = x*y;
				m_Numbers[n + 1] = QString::number(result, 'f', 5);
				m_Numbers.removeAt(n);
				m_Symbols.removeAt(n);
			}
			else
			{
				double result = x / y;
				m_Numbers[n + 1] = QString::number(result, 'f', 5);
				m_Numbers.removeAt(n);
				m_Symbols.removeAt(n);
			}
			continue;
		}
		n++;
	}
	if (m_Symbols.length() != 0)
	{
		addition();
	}
	else
	{
		m_result.append(m_Numbers[0]);
	}

}
           

         

  1. 加法的处理:addition()函数代码如下
void Calculate::addition()
{
	int a = 0;
	for (; a < m_Symbols.length(); )
	{
		double x = 0;
		double y = 0;
		double result = 0;
		x = m_Numbers.at(a).toDouble();
		y = m_Numbers.at(a + 1).toDouble();
		if (m_Symbols.at(a)=="+")
		{
			result = x + y;
			m_Numbers[a + 1] = QString::number(result);
			m_Numbers.removeAt(a);
			m_Symbols.removeAt(a);
		}
		else
		{
			result = x - y;
			m_Numbers[a + 1] = QString::number(result);
			m_Numbers.removeAt(a);
			m_Symbols.removeAt(a);
		}
	}
	m_result.append(m_Numbers.at(a));
}
           

         以上就是本计算的主要功能代码!

  该计算机的健壮性方面为进行完善,只是对Qt熟悉的一个小项目,有什么建议的可以在评论中提出。

如需要源码请转至:资源下载中心

  第一次写博客有问题的希望能够指出。(错别字请理解)

继续阅读