Qt - calculator - - 计算器

更新时间:2024-03-11 05:32:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

题目:科学计算器

姓名:张XX学号:2010XXXXXX专业:信息工程 姓名:张XX学号:2010XXXXXX专业:信息工程 姓名:饶XX学号:2010XXXXXX专业:信息工程 姓名:蒲XX学号:2010XXXXXX专业:信息工程 姓名:陈XX学号:2010XXXXXX专业:信息工程

201x年x月x日

1 引言

1.1 设计背景

● 计算器(calculator;counter)一般是指“电子计算器”,计算器是能进行数学运算的手持机器,拥有集成电路芯片,其结构简单,比现代电脑结构简单得多,可以说是第一代的电子计算机(电脑)。计算器这一小小的程序机器实际上是从计算机中割裂出来的衍生品,虽然功能较单一,但因其操作模式的方便快捷和价格的低廉,携带方便等特点,已经被广泛应用于工程、学习、商业贸易等日常生活中,极大的方便了人们对于数字的整合运算,成为人们生活和办公中的必备品之一,深得使用者的青睐。

●计算器在我们的日常生活扮演着很重要的角色,因此不断设计开发出功能更强大,携带更轻便,使用更加快捷迅速的计算器便成为相应工作者奋斗的目标和任务。

1.2 设计目的

● 进一步了解C++语言和高级程序设计语言的结构,了解其好处和可用性,掌握基本的程序设计过程和技巧,掌握基本的分析问题、利用计算机求解问题的能力,具备初步的高级语言程序设计能力。为后续计算机课程和毕业设计打下坚实基础。

● 通过该计算器程序软件的设计,培养独立思考、综合运用所学有关相应知识的能力,更好地巩固《C++程序语言设计》和《高级程序设计》课程学习的内容,掌握工程软件设计的基本方法,强化上机动手编程能力,体验理论与实践相结合的过程,同时培养同学之间的团队合作精神,体会在工作中团队合作的重要性和必要性。

2.功能需求分析

2.1 功能划分

● 本次我们设计的计算器在功能上大致与Windows系统自带的计算器程序相似,但在某些细节处加入了我们设计同学的独特创新和技巧,具体体现见详细设计部分。对于我们所设计的科学计算器,其功能大致可以如下划分:

① 算术型计算器功能——可以进行加(+)、减(-)、乘(*)、除(/)、开方(sqrt)、百分数(%)等简单算术计算。

② 科学型计算器功能——可以进行乘方、开方、指数、对数、三角函数、等方面的运算。

③ 一元运算和多元运算——可以进行表达式和简单运算,且切换较为快捷。 ④ 技巧创新功能——开机画面,图片的插入,用户使用后数据的记录。

2.2 功能描述

● 对于算术型计算器的功能大家已经非常熟悉,就不再赘述。这里只对科学型计算器功能中的特殊符号、必要函数及技巧创新功能部分作简单描述。

① 特殊符号和函数

Pi —— π 。即 3.1415926?

Ln ——自然对数,ln(x)是以e为底的x的对数 Log ——以10为底的对数,10是可以省略的

S in ——正弦函数 Arcsin ——反正弦函数 Cos ——余弦函数 Tan ——正切函数 n! ——阶乘

Mod ——取模运算 Clear ——清空

等等这些符号有利于我们计算,方便快捷的得出结果。

②创新部分

开机画面:计算器启动时,程序会生成一个我们预先设计的图片作为计算器的启动画面,因与手机电脑等开机画面相似,所以我们称之为开机画面,这一小功能虽然没有实际用途,但改变了一般传统计算器给用户的印象,丰富了视觉,让使用者眼前一亮,增加了愉悦感。

图片插入:当使用者使用我们计算器的时候,在计算器运行界面的About us一栏,用户可以看到我们设计者的合照。这点算是我们设计者的小创新吧。

使用数据记录:我们都知道,现在市面上一般的计算器虽然在计算上能满足用户的需求,但对于一些重要的数据和运算过程、记录,就无法实现重要过程和数据的记录,所以这项功能的添加让我们的计算器更加科学化,人性化,用户不必要再担心运算的出错和检查的麻烦。这也是我们所设计的计算器相比于其他计算器的重要优点之一。

2.详细设计

2.1 普通计算功能

(1)界面设计

界面设计我们是使用Qt creator进行设计的,首先创建一

QMainWindow(parent).ui,这个界面为QWidget。然后在左侧的Widget Box找相应的控件添加到QMainWindow(parent)t里。首先提出一个lineEdit控件作为算式显示窗口和结果显示窗口,在提取出30个QpushButton为0到9按键和加减乘除按键、括号按键、开根号按键、小数点按键、%按键、取模按键、阶乘按键、取倒按键、等于按键、历史按键、标准/科学模式切换按键。然后再把各个pushButton名字改成相应的符号,并且改对应pushbutton的属性,保存后取Qt creator编译QMainWindow(parent).ui,运行程序就可以显示相应界面。

具体界面设计效果如下:

且各组件的属性设置如下:

(2)程序具体实现

现在.h文件中对各个按键在私有槽中进行声明,例如:

public slots:

void clickbtn1();

就对1键(槽函数)进行声明,然后就可以在.cpp进行编写程序。声明first,second两个整形表示第一个输入和第二个输入,然后用Qt(Qstring)封装好的append()函数进行添加,当然,这里牵涉到本程序对Btn按键的函数声明,并且使用setText函数,使其按键符号点击后可以在lineEdit上显示,在这里用的是信号和槽的机制,具体的信号于槽的链接在后面会详细说明。

2.2 科学计算器功能

本界面的主要功能是在普通计算器的基础上,添加了一些科学计算的功能,

具体实现的操作功能包括三角函数运算(sin()、cos()、tan()、cot())、反三角函数运算(arcsin()、raccos()、arctan()、arccot())、双曲三角函数运算(sinh()、cosh()、tanh()、coth())、对数运算(log、、 lg、ln)

x2xx弧度运算、角度运算、梯度运算。 (1)界面设计

为了隐藏的需要,我们采用Group Box的组件,然后设置“通过点击“变为“

”按键可将窗口由标准型切换为科学型(此时“

”按键,”按键

”按键,再点击一次即可变回标准型),切换为科学型窗口后,在

普通窗口的基础上添加一些QPushButton按钮,修改其属性,使其变成相应的功

能键,再从左边把QComboBox拖到科学计算窗口中,并修改其属性,用户可以在下拉框中,选择自己想要实现的运算类型(如:弧度、梯度;不同对数运算),然后用对上述按键在窗口中进行合理布局,最后用QtCreator对所设计的界面进行编译形成ui文件,点击运行即可查看所设计界面。

具体界面设计效果如下:

下拉框中显示的设计如下:

各组件的属性设置如下:

(2)程序具体实现

这里仍使用信函和槽连接机制,我们没有使用信号和槽编辑器,而是直接在.cpp文件中添编写其代码来实现,首先在.h文件中对各个按键进行声明,如:void clicksin();就是对sin按键进行声明,再到.cpp文件中编写相应的代码实现其功能,当Jing_zhan_unary变量为ture时,执行

clickTrigJIng_zhan_TS(“sin”),或当Jing_zhan_Expression变量为ture时,执行sinBian_lian=true;clickJing_zhan_Pro(\实现sin的运算功能。

2.3 计算历史显示功能

本模块包括本系统的删除、保存功能。 (1)界面介绍

这里我要用两个QpushButton控件和一个LineEdit控件,两个QpushButton控件分别表示删除算式、算式另存为,在修改其属性,再拖拽一个LineEdit控件,它用来显示计算机执行的历史事件,而且还可以在其上点击选择算式。

具体界面设计效果如下:

各组件的属性设置如下:

(2)程序具体实现

另存为算式:首先声明一个另存为的函数void

chendahao::clickHistorySaveas(),添加一个QFileDialog控件作为另存为显示窗口,再把QFileDialog名字改成相应的另存为,并且改对应QFileDialog的属性,然后查询算式表(message),查找最后一个id的值,然后id加一,再把次id和窗口提取的算式存入数据库算式表(message)中,然后通过槽函数ui->statusBar->showMessage(Version+\已保存\查询整个message表把表中的内容显示出来。

删除算式:先用currentIndex().row()把鼠标点中的行选中。提出行数,声明model,再用model中封装好的函数删除这一行,在加上警告函数,判断是否删除,就可以了。

2.4 删除功能

此功能为删除窗口中的最后一个字符,具体编写过程为:提取窗口中的内容,并把窗口中的内容存放到一个QString型变量中,然后用Qt现有的已经封装好的函数,把这个变量从左边开始将其最后一个字符去掉,使其长度减少一,将改变后的字符串在存放到这个变量中,再把这个变量重新返回到窗口中,这样就达到删除的功能了。

2.5 清空功能

此功能为清空显示窗口,这里用Qt封装好的函数clear(),直接把窗口给清空,这样就达到效果。

2.6 帮助功能

在菜单栏里的“about us”按键是本系统的帮助功能,其中包括“618”选项和“about Qt”选项两个子选项,其中“about Qt”介绍了有关Qt软件的相关信息。“618”按键介绍了科学计算器的制作团队各成员姓名和学号以及陈皓同学的空间连接。

具体(618)界面设计效果如下:

各组件的属性设置如下:

2.7 操作类型切换功能

在菜单栏里添加操作类型选择按键,在操作类型按键下有一元顺序运算和表达式运算两个子选项,当选择一元顺序运算时,将“(”按键和“)”按键设置为不可点击即,而当选择表达式运算时,将“1/x”按键和“±”按键设置为不可点击。由于在不同的操作类型下,有些运算符不适用,故将其设置为不可点击, 这样可以防止用户进行违规操作。

具体界面设计效果如下:

3.系统的实现:

计算分简单计算和科学计算两种功能,又由于要实现表达式的功能,故应该将其分开实现,所以,我们在程序中设置了两逻辑变量进行区分,如下所示。 bool Jing_zhan_unary=false; //一元操作 bool Jing_zhan_Expression=true; //表达式操作

当然,对于下面具体步骤中出现的函数,我们有必要在此说明,这其中也包

括整个程序的核心算法。

考虑到程序中出现了众多信号与槽的链接,故采用手工链接的方式进行。 首先在chendahao.h中声明如下槽函数: public slots:

void clickSifirla(); void click_chenhaoQQ(); void clickbtn(QString); void clickbtn1(); void clickbtn2(); void clickbtn3(); void clickbtn4(); void clickbtn5(); void clickbtn6(); void clickbtn7(); void clickbtn8(); void clickbtn9(); void clickbtn0(); void clickPoint();

void clickPointControl(); void clickClear(); void clickPlus(); void clickDecrease(); void clickMultiply(); void clickEliminate(); void clickEql();

void clickJing_zhan_();

void clickJing_zhan_2(QStringList &diziPro,QString isaret); void clickBackspace(); void clickChangesign(); void clickSqrt(); void click_G(); void clickCi(); void click_1_x();

void clickJie_cheng(); void clickSwitch(); void clickSimple(); void clickSin(); void clickCos(); void clickTan(); void clickCot(); void clickPi(); void clickE();

void clickArcsin(); void clickArccos();

qian_.append(\);

ui->LineEdit1->setText(qian_); }

safetyJing_zhan_=false; }

else if(Jing_zhan_Expression==true) {

clickbtn(\); } }

说完计算器Btn键的功能实现,接下来,对于任何计算器,其“≒”键无意是对计算器功能的实现的直接展示。对于一般的简单计算器,由于有Math.h的支持,实现起来较为容易,但是,对于表达式计算器,这就是对我们整个程序逻辑关系的真确与否的直接表现,可想其重要性。

具体代码如下:

void chendahao::clickEql() {

if(Jing_zhan_unary==true) {

if(mu_qianEql==false) {

clickJing_zhan_();

safetyJing_zhan_=false; Jing_zhan_Bian_lian=true; pointBian_lian=false; first_shu=true; Jing_zhan_=\; } }

else if(Jing_zhan_Expression==true) {

mu_qianEql=true;

qian_= ui->LineEdit1->text(); qian_.append(\);

ui->LineEdit1->setText(qian_); clickJing_zhan_(); } }

可能大家看到这里会觉得这不算什么,其实不然,因为大多数程序都被封住在void clickJing_zhan_()函数中。接下来,我们将进入本程序的核心代码中,由于代码过长,考虑到简单计算器运算实现的简单性,我们只列举出如下关于表达式部分的代码(void clickJing_zhan_()中)。 else if(Jing_zhan_Expression==true) {

if(ZkuohaoCounter!=YkuohaoCounter) {

qDebug(\错误\); } else {

backuptext=ui->LineEdit1->text();

ui->texthistory->insertPlainText(QString::number(history_Counter)+\ -> \+backuptext); for(int

triCounter=0;triCounter

backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); backuptext.replace(QString(\),QString(\)); }

backuptextBas=backuptext; backuptextSon=backuptext;

int Counter=0; //计数器 while(Counter

int size=backuptext.size();

yer=backuptext.indexOf(ArrayJing_zhan_sign.value(Counter)); ArrayyeIsaret=backuptext.at(yer); backuptextBas.remove(yer,size-1); backuptextSon.remove(0,yer+1); Array.append(backuptextBas); Array.append(ArrayyeIsaret); backuptext=backuptextSon; backuptextBas=backuptextSon;

Counter=Counter+1; }

int yerEql=backuptextSon.indexOf(\); backuptextSon.remove(yerEql,yerEql); Array.append(backuptextSon); Array.append(\); qDebug()<

if(kuohaoBian_lian==true) {

while(Array.contains(\)==true) {

int ZkuohaoYer=Array.lastIndexOf(\);

int YkuohaoYer=Array.indexOf(\,ZkuohaoYer); for(int

kopyaCounter=ZkuohaoYer+1;kopyaCounter<=YkuohaoYer;kopyaCounter++) {

Arraykuohao.append(Array.value(kopyaCounter)); }

clickJing_zhan_2(Arraykuohao,\);

Array.replace(ZkuohaoYer,QString::number(Results));

for(int i=ZkuohaoYer+1;i<=YkuohaoYer;i++) {

int i2=ZkuohaoYer+1; Array.removeAt(i2); }

if(Array.value(ZkuohaoYer-1)==\) {

Array.removeAt(ZkuohaoYer-1); Array.removeAt(ZkuohaoYer); }

Arraykuohao.clear(); }

kuohaoBian_lian=false; }

clickJing_zhan_2(Array,\); } } }

当然,对上面的理解可以从这个角度来看。因为我们要实现表达式运算,而对于表达式运算的实现,最主要的不是各个功能键的实现,而是对数据的储存和对左右括号的判断。这个可以从以前学习数据结构中的栈进行联系。当然,我们必须承认这个过程的程序编写是有难度的,它不仅考察各人的程序编写能力,同

时也考察了我们逻辑思维方面的能力。所以,在这里,我必须再次感谢QTCN论坛的广大Qt爱好者对我们的帮助,是你们让我在最困难的时候继续坚持,同时,也必须对ehm 先生致以同样的感谢,是你让我们确定了课题的发展方向,让我们看到了Qt 在String上较比C++的飞速进步,让我们抛弃了原有的思路(当然,这是飞跃,应该提倡)。当然,要理解表达式计算器的设计思想,还是要从最初的方法来讲,如图所示:

以上程序具体只是为我们开辟了表达式计算器实现的可能,具体的计算实现过程封装在void clickJing_zhan_2()中,这里就不指出,详细过程见附录。最后,出于对本设计科学方面计算实现说明的目的,我们举出了程序中,在这部分中最为核心的代码,也就是在进行表达式计算时,调用的函数void clickTrigJing_zhan_IO() 如下:

void chendahao::clickTrigJing_zhan_IO(QStringList &ArrayPro,bool &trigBian_lian,QString Jing_zhan_,QString Jing_zhan_sign) {

if(Jing_zhan_Expression==true) {

if(trigBian_lian==true) {

do {

int trigYer=ArrayPro.indexOf(Jing_zhan_sign); QString chtrig=ArrayPro.value(trigYer-1); if(chtrig==\) {

QString trig_shu=ArrayPro.value(trigYer+1); double trig_shudouble=trig_shu.toDouble();

if(Jing_zhan_==\||Jing_zhan_==\||Jing_zhan_==\||Jing_zhan_==\)

{

trig_shudouble=clickDonusum(1,trig_shudouble); if(Jing_zhan_==\) {

tempResults=sin(trig_shudouble); }

if(Jing_zhan_==\) {

tempResults=cos(trig_shudouble); }

if(Jing_zhan_==\) {

tempResults=tan(trig_shudouble); }

if(Jing_zhan_==\) {

tempResults=tan(trig_shudouble); tempResults=1/tempResults; } } else {

if(Jing_zhan_==\) {

tempResults=asin(trig_shudouble); }

if(Jing_zhan_==\) {

tempResults=acos(trig_shudouble);

3.2其中各功能键的具体实现:

//加法运算

void chendahao::clickPlus() {

clickJing_zhan_Pro(\,\,mu_qianPlus); pointBian_lian=false; }

//减法运算

void chendahao::clickDecrease() {

clickJing_zhan_Pro(\,\,mu_qianDecrease); pointBian_lian=false; }

//乘法运算

void chendahao::clickMultiply() {

clickJing_zhan_Pro(\,\,mu_qianMultiply); pointBian_lian=false; }

//除法运算

void chendahao::clickEliminate() {

clickJing_zhan_Pro(\,\,mu_qianEliminate); pointBian_lian=false; }

// ^ 幂的运算

void chendahao::clickCi() {

clickJing_zhan_Pro(\,\,mu_qianCi); }

// n! 阶乘的实现

void chendahao::clickJie_cheng() {

if(Jing_zhan_unary==true) {

if(safetyJing_zhan_==true) {

qDebug(\错误\); } else {

int Jie_cheng=1; clickEql();

qian_Double=ui->LineEdit1->text().toDouble(); double Jie_chengCounter=qian_Double; while(Jie_chengCounter>0) {

Jie_cheng=Jie_cheng*Jie_chengCounter; Jie_chengCounter=Jie_chengCounter-1; }

ui->LineEdit1->setText(QString::number(Jie_cheng));

ui->texthistory->insertPlainText(QString::number(history_Counter)+\ -> \+QString::number(qian_Double)+\ ! =\+QString::number(Jie_cheng)+\);

history_Counter=history_Counter+1; } }

else if(Jing_zhan_Expression==true) {

clickJing_zhan_Pro(\,\,mu_qianJie_cheng); Jie_chengBian_lian=true; } }

3.3操作类型的切换

// 操作类型键的 切换

void chendahao::clickReplaceTur(QLabel *labelcaozuoleixing,QLabel *label2caozuoleixing,bool Jing_zhan_caozuoleixing) {

labelcaozuoleixing->show(); label2caozuoleixing->hide(); ui->LineEdit1->setText(\); clickSifirla(); Jing_zhan_=\;

ui->statusBar->addWidget(labelcaozuoleixing); //一元类型

if(Jing_zhan_caozuoleixing==Jing_zhan_unary) {

Jing_zhan_unary=true;

Jing_zhan_Expression=false;

ui->btnChangesign->setEnabled(true);

ui->btn_1_x->setEnabled(true); ui->btnZkuohao->setEnabled(false); ui->btnYkuohao->setEnabled(false); ui->action_unary->setChecked(true);

ui->action_Expression->setChecked(false); }

//多元类型(表达式)

else if(Jing_zhan_caozuoleixing==Jing_zhan_Expression) {

Jing_zhan_unary=false; Jing_zhan_Expression=true;

ui->btnChangesign->setEnabled(false); ui->btn_1_x->setEnabled(false); ui->btnZkuohao->setEnabled(true); ui->btnYkuohao->setEnabled(true); ui->action_unary->setChecked(false);

ui->action_Expression->setChecked(true); } }

图2 操作类型切换

3.4 通过如此设置后可以有带表达式的运算或者不带。带表达式的如下图:

图3 带表达式的界面

3.5简单计算和科学计算的切换:

为适应不同的计算需求,设置了科学计算和简单计算,其主要程序及代码如下所示:

// 科学 与 简单 类型的切换 void chendahao::clickSwitch() {

if(ui->gbMat->isHidden()==true) {

ui->gbMat->show();

ui->btnSwitch->setText(QChar(0x2191)); //上下符号 ui->action_Ke_xue->setChecked(true); //科学 } else {

ui->gbMat->hide();

ui->btnSwitch->setText(QChar(0x2193));

ui->action_Ke_xue->setChecked(false); //科学

}

运行后界面如下图:

图4 科学计算界面

3.6历史记录

其实现代码如下:

3.6.1历史删除功能

//历史Goup -----历史.删除

void chendahao::clickHistoryDelete() {

ui->texthistory->clear(); history_Counter=1;

ui->statusBar->showMessage(Version+\ : \+tr(\已删除\),10000); }

3.6.2 历史另存为功能

void chendahao::clickHistorySaveas() {

标准型显示界面

科学型显示界面

4.1个别按键功能及使用方法介绍:

(1)

:退格键,可以删除窗口中从左边起最后一个字符。

运行测试:在窗口中输入:

使用一次退格键以后显示结果:

(2):开方,如需要对常数x进行开方,则可在窗口中先点击开方键,再输入x。

运行测试:对9进行开方运算,在窗口中输入

点击等于号之后窗口中所显示结果之后窗口中所显示结果:

(3):百分号,如在窗口中输入x%,则运算后显示的为将x除以100后的结果。

运行测试:在窗口中输入

点击等于号之后窗口中所显示结果之后窗口中所显示结果

(4):幂运算,如在窗口中输入x^y,则是求x的y次幂。

运行测试:在窗口中输入

点击等于号之后窗口中所显示结果

(5):质数运算,即对所输入数字x进行因式分解,将其分解为若干个质数的和。使用方法为先输入需分解的数x,在点击质数运算按键即可。 运行测试:在窗口中输入

点击质数运算按键后所显示运行结果

(6)

:阶乘,此运算符只能对正整数进行运算,当输入正整数

x时,系统所执行的算法为:x*(x?1)*?*2*1。

运行测试:在窗口中输入

点击等于号之后窗口中所显示结果

(7)

:模运算,即xmody所得结果为,x除以y后所得余数的

值。

运行测试:在窗口中输入

点击等于号之后窗口中所显示结果

(8)

(9)

(10)

:此按键可将计算器在标准型和科学型之间进行切换,:自然对数。 :圆周率。

从标准型切换为科学型后,按键图标变为换回标准模式并且图标变为最初的摸样。

,再点击一次即可切

(11):点击此按键课可显示计算器之前执行过的运算。如在标准型下点击此按键,标准型显示界面变为如下:

如在科学型下点击此按键,将多出如下界面:

科学型显示界面变为如下:

本文来源:https://www.bwwdw.com/article/zu98.html

Top