基于QT实现的计算器(只需要简单的栈知识,不仅仅是四则运算,接近手机内置计算器功能)

参考文献:Qt 5.9 C++开发指南 (王维波等 著)及众多网上资料

1.问题定义及需求分析

课题目的:

由输入的四则算术表达式字符串,动态生成算术表达式所对应的后缀式,通过后缀式求值并输出;

输出的形式:界面上:以QT中的Text Browser进行输出结果。后台:通过suffix文件输出表达式的后缀表达式。

程序的功能:在布局和功能上,我们以小米内置计算器为标准。在运算上:我们实现了三角函数,反三角函数,次方,根号,ln,log,1/x,阶乘的在允许括号和简写的复合运算。在输出上:我们实现了退格,多次运算换行输出,一次ac一次运算的功能。

测试数据:通过图形界面输入多个表达式,多次操作检验每个按钮的功能。

2.概要设计

抽象数据类型的定义:起初我们通过数组实现了一个char-stack,实现pop,push,top操作。

主程序的流程:创造图形界面,打开文件suffix,通过pushbutoon进行交互,输出结果。

各程序模块之间的调用关系:main函数里调用qt内置的图形界面创建程序,接着在图形界面的模块上(我们采用了dialog为基础窗口)调用我们自己写bds_qz.h模块。

3.详细设计

3.1.图形界面的设计:我们通过QT的designer设计模式设计了像小米内置计算器的界面。

3.2. 运算算法:我们参考了网上的四则运算的算法,但同时又进行了一些自己的创新。

首先,我们处理的是一个中缀运算表达式,我们从左向右开始遍历,分为运算符和数字的判断。

数字的判断及存储:

存储:我们没有采取栈的结构,我们用了一个double数组加一个int numpos代表最前面的数字位置,实现存储和增减操作。
代码:double num[50] ;int numpos = 0;

判断:整数部分:碰到一个数字则往后遍历找直到不为数字,期间遍历的字符通过ASCII码值减去0的ASCII码值映射,再通过10为基的乘法映射求出整数。

小数部分:在遍历完整数部分后,立即判断后面有没有小数点,如果有以整数的方法不过以0.1为基求出小数部分。

符号部分:当我们遍历时碰到第一个数字立即往前找前面是不是(——,如果是则在最终转化完后乘以负一。

数字特殊情况分为π和e,π和e则采用了判断等效替代的方法(如如果按了π按钮,则用3.1415926代替)。

代码:if (bds[i] <= '9'&&bds[i] >= '0')//为数字的情况,转换为1个数,如234

            {

                num[++numpos] = 0;

                while (bds[i] <= '9'&&bds[i] >= '0')

                {

                    num[numpos] *= 10;

                    num[numpos] += (bds[i] - '0');

                    ++i;

                }

                if (bds[i] == '.')

                {

                    double f_car=0.1;//定义基数

                    ++i;

                    while (bds[i] <= '9'&&bds[i] >= '0')

                    {

                        num[numpos] += ((bds[i] - '0')*f_car);

                        f_car *= 0.1;

                        ++i;

                    }

                }//计算小数点

   else if(bds[i]=='('&&bds[i+1]=='-')

            {

                i+=2;

                num[++numpos] = 0;

                while (bds[i] <= '9'&&bds[i] >= '0')

                {

                    num[numpos] *= 10;

                    num[numpos] += (bds[i] - '0');

                    ++i;

                }

                if (bds[i] == '.')

                {

                    double f_car=0.1;//定义基数

                    ++i;

                    while (bds[i] <= '9'&&bds[i] >= '0')

                    {

                        num[numpos] += ((bds[i] - '0')*f_car);

                        f_car *= 0.1;

                        ++i;

                    }

                }//计算小数点

                num[numpos]*=-1;

                suffix<<num[numpos]<<' ';

                i+=1;

            }//

            else if(bds[i]=='p')

            {

                num[++numpos]=3.14159265358;

                 suffix<<"Π"<<' ';

                ++i;

            }

            else if(bds[i]=='e')

            {

                num[++numpos]=2.71828182845;

                suffix<<'e'<<' ';

                ++i;

            }

运算符的判断,映射,存储,操作,:

判断:不为数字且不为括号且不为π和e及负号。

映射:因为有的操作运算符比如ln,log等,它不如+-等占一个字节,但我们遍历时一个个字节遍历字符串的,所以我们采用了映射技术。

代码:std::string char_change(char s)

{

        if(s=='*')

            return "x";

        else if(s=='/')

           return  "÷";

        else if(s=='n')

            return  "ln";

        else if(s=='g')

           return  "lg";

        else if(s=='p')

            return "Π";

        else if(s=='s')

           return  "sin";

        else if(s=='c')

            return  "cos";

        else if(s=='t')

           return  "tan";

        else if(s=='a')

          return  "arcsin";

        else if(s=='b')

            return  "arccos";

        else if(s=='d')

           return  "arctan";

        else if(s=='\n')

            return "\r\n";

        else if(s=='u')

           return  "°";

        else

        {

            std::string ss(1,s);

            return ss;

        }

}

存储:采取栈的结构。

       代码:char pop(stack *p)

{

    if (p->size == 0)

    {

        printf("空栈");

        return '\0';//抛出/0字符代表空

    }

    else

    {

        --(p->size);

        return p->a[p->size];

    }

}

char top(stack *p)

{

    if (p->size == 0)

        return '\0';//抛出/0字符代表空

    else

    {

        return p->a[p->size - 1];

    }

}

int empty(stack *p)

{

    return p->size==0;

}

void push(stack *p, char b)

{

    p->a[p->size] = b;

    ++p->size;

}

操作:对于一个运算符,我们先判断栈是否为空,为空直接入栈,如果栈不为空,我们则通过一个优先级函数分别求出栈顶运算符的优先级,和当前运算符的优先级,并将他们进行比较。如果栈顶的元素优先级大于等于当前运算符,执行出栈操作,直到栈为空或者栈顶元素优先级小于当前运算符,后将当前运算符入栈。注意的是()会改变运算顺序,我们只将(入栈,如果碰到)就将左括号到栈顶的元素全部弹出。

出栈操作代码:else

            {

 

               if (empty(ysf))//栈为空的情况

                    push(ysf, bds[i]);

                else

                {

                    if (bds[i] == '(')

                        push(ysf, bds[i]);

                    else if (bds[i] == ')')//右括号的情况

                    {

                        while (top(ysf) != '(')

                        {

                            operat(num,numpos,top(ysf));//调用对数据运算的函数

                            suffix<<char_change(top(ysf))<<' ';

                           pop(ysf);

                        }

                        pop(ysf);//弹出右括号

                    }

                    else

                    {

                        while (compare(bds[i])<=compare(top(ysf)))//优先级映射函数

                        {

                            operat(num,numpos,top(ysf));

                          suffix<<char_change(top(ysf))<<' ';

                             pop(ysf);

                        }

                        push(ysf, bds[i]);

                    }

                }

                ++i;

            }

        }

        while (!empty(ysf))//最后的出栈

        {

             operat(num,numpos,top(ysf));

              suffix<<char_change(top(ysf))<<' ';

             pop(ysf);

        }

优先级函数代码:int compare(char a)//用于比较优先级

{

    int i;

    switch (a)

    {

    case '+':

        i = 1;

        break;

    case '-':

        i = 1;

        break;

    case '*':

        i = 2;

        break;

    case '/':

        i = 2;

        break;

    case '^':

        i = 3;

        break;

    case 'v':

        i =4;

        break;

    case 's':

        i =4;

        break;

    case 'c':

        i =4;

        break;

    case 't':

        i =4;

        break;

    case 'g':

        i =4;

        break;

    case 'n':

        i =4;

        break;

    case 'a':

        i =4;

        break;

    case 'b':

        i =4;

        break;

    case 'd':

        i =4;

        break;

    case '!':

        i =5;

        break;

    case '%':

        i = 5;

        break;

    case 'u':

        i = 9;

        break;

    default:

        i = 0;

        break;

    }

    return i;

}

数字运算代码:void merge(double *a, double b, char c)//用于将两数字合并,注意前面的数字传地址

{

    if (c == '-')

    {

        (*a) -= b;

    }

    else if (c == '+')

    {

        (*a) += b;

    }

    else if (c == '*')

    {

        (*a) *= b;

    }

    else if(c=='/')

        (*a) /= b;

    else if(c=='^')

         {*a=pow(*a,b);}

}

void operat(double *num,int &numpos,char c)

{

    if (c == '%')

    {

        num[numpos] /= 100;

    }

    else if(c=='v')

    {

        num[numpos] = sqrt(num[numpos]);

    }

    else if(c=='g')

    {

        num[numpos] = log10(num[numpos]);

    }

    else if(c=='n')

    {

        num[numpos] = log1p(num[numpos]-1);

    }

    else if(c=='s')

    {

        num[numpos] = sin(num[numpos]);

    }

    else if(c=='a')

    {

        num[numpos] = asin(num[numpos]);

    }

    else if(c=='c')

    {

        num[numpos] = cos(num[numpos]);

    }

    else if(c=='b')

    {

        num[numpos] = acos(num[numpos]);

    }

    else if(c=='t')

    {

        num[numpos] = tan(num[numpos]);

    }

    else if(c=='d')

    {

        num[numpos] = atan(num[numpos]);

    }

    else if(c=='u')

    {

        num[numpos] = num[numpos]*3.14159265358/180;

    }

    else if (c == '!')

    {

        long sum=1;

        int nums=num[numpos];

        for(int i=2;i<=nums;++i)

        {

            sum*=i;

        }

        num[numpos] =sum;

    }

    else

    {

        merge(&num[numpos - 1], num[numpos], c);

        --numpos;

    }

}

4.调试分析:

4.1对所遇问题的解决方法及分析:

碰到的问题和改进较多。

首先输出框上:

例如√运算符,我希望在在输出框显示根号,但QString确实写入了√,但在insetrhtml时,却加载不进去,迫不得已如图 我们显示了用v代替了√。

还有就是换行ac,因为实际在使用小米计算器时,它的ac时,一次ac一条运算。还有退格运算,你要让它可以退格当前运算,而不影响前一次运算。这其中就涉及了一些字符串的处理,还有QString和string还有char*(因为我们最初写的四则运算是纯C的)转换,花了一些时间。

运算功能上:

第一张图为小米的,第二张为我们,仔细对比会发现,小米上是有deg和rad这个按钮的,即它可以通过一个按钮,来调整运算是采用弧度制还是角度制。而且它的文本框,还要随del和ac时改变。考虑到开发难度,我们的创新就是添加一个新的运算符°(它拥有最高的优先级,将一个数➗π*180),实现了相同的功能。

其次就是小米的计算器是实时运算的,既不用按=也会计算结果,但我们这个不是,我们放弃了这个功能,因为如果这样,就必须实时调用函数,而不是按一次=调用(占用了更多的资源),而且我们没有非法检测,如果中途表达式错了(如sin(90°+1)!)我们无法检验出错,故放弃了。

额外:还有一个问题就是发布程序的问题,希望自己写的东西在别人的电脑也能运行。起初单纯的一位按照release编译就行,然后 ,经过上网查阅,我们知道是程序的依赖关系的问题,它缺乏相应的dll,而且吧因为QT装的是VS的编译器,还需要msvc的dll。在经历了诸多查阅和实践后,我们解决了这个问题,也让我们意识到程序的发布其实也是一个复杂的问题。

4.2算法的时空分析及改进思想

由于算法分为了很多部分,对于一次=运算核心部分是遍历一遍表达式字符数组复杂度为O(n)。但在循环里面,涉及一层while循环的出栈操作,不过仔细分析,每个运算符入栈和出栈操作是唯一的,即它们的复杂度一定小于O(2n),故一次=运算总复杂度为O(n)。

整个程序的复杂度将是你执行运算的次数*O(n)。

QT版:

 

控制台四则运算版:

7.附录

Main.c

#include "dialog.h"

#include <QApplication>

int main(int argc, char *argv[])

{

 

    QApplication a(argc, argv);

    Dialog w;

    w.show();

    return a.exec();

}

bds_qz.h

#ifndef BDS_QZ_H

#define BDS_QZ_H

#include<string>

#include<sstream>

#include <stdio.h>

#include <stdlib.h>

#include<cmath>

#include<fstream>

#define n 50

typedef struct

{

    char a[n];

    int size;//表示栈中含有的元素数量

} stack;

char pop(stack *p);

char top(stack *p);

int empty(stack *p);

void push(stack *p, char b);

int compare(char a);//用于比较优先级

void merge(double *a, double b, char c);//用于将两数字合并,注意前面的数字传地址

std::string qiuzhi(const char *bds);

std::string char_change(char s);

#endif // BDS_QZ_H

 

bds_qz.cpp

#include"bds_qz.h"

char pop(stack *p)

{

    if (p->size == 0)

    {

        printf("空栈");

        return '\0';//抛出/0字符代表空

    }

    else

    {

        --(p->size);

        return p->a[p->size];

    }

}

char top(stack *p)

{

    if (p->size == 0)

        return '\0';//抛出/0字符代表空

    else

    {

        return p->a[p->size - 1];

    }

}

int empty(stack *p)

{

    return p->size==0;

}

void push(stack *p, char b)

{

    p->a[p->size] = b;

    ++p->size;

}

int compare(char a)//用于比较优先级

{

    int i;

    switch (a)

    {

    case '+':

        i = 1;

        break;

    case '-':

        i = 1;

        break;

    case '*':

        i = 2;

        break;

    case '/':

        i = 2;

        break;

    case '^':

        i = 3;

        break;

    case 'v':

        i =4;

        break;

    case 's':

        i =4;

        break;

    case 'c':

        i =4;

        break;

    case 't':

        i =4;

        break;

    case 'g':

        i =4;

        break;

    case 'n':

        i =4;

        break;

    case 'a':

        i =4;

        break;

    case 'b':

        i =4;

        break;

    case 'd':

        i =4;

        break;

    case '!':

        i =5;

        break;

    case '%':

        i = 5;

        break;

    case 'u':

        i = 9;

        break;

    default:

        i = 0;

        break;

    }

    return i;

}

std::string char_change(char s)

{

        if(s=='*')

            return "x";

        else if(s=='/')

           return  "÷";

        else if(s=='n')

            return  "ln";

        else if(s=='g')

           return  "lg";

        else if(s=='p')

            return "Π";

        else if(s=='s')

           return  "sin";

        else if(s=='c')

            return  "cos";

        else if(s=='t')

           return  "tan";

        else if(s=='a')

          return  "arcsin";

        else if(s=='b')

            return  "arccos";

        else if(s=='d')

           return  "arctan";

        else if(s=='\n')

            return "\r\n";

        else if(s=='u')

           return  "°";

        else

        {

            std::string ss(1,s);

            return ss;

        }

}

void merge(double *a, double b, char c)//用于将两数字合并,注意前面的数字传地址

{

    if (c == '-')

    {

        (*a) -= b;

    }

    else if (c == '+')

    {

        (*a) += b;

    }

    else if (c == '*')

    {

        (*a) *= b;

    }

    else if(c=='/')

        (*a) /= b;

    else if(c=='^')

         {*a=pow(*a,b);}

}

void operat(double *num,int &numpos,char c)

{

    if (c == '%')

    {

        num[numpos] /= 100;

    }

    else if(c=='v')

    {

        num[numpos] = sqrt(num[numpos]);

    }

    else if(c=='g')

    {

        num[numpos] = log10(num[numpos]);

    }

    else if(c=='n')

    {

        num[numpos] = log1p(num[numpos]-1);

    }

    else if(c=='s')

    {

        num[numpos] = sin(num[numpos]);

    }

    else if(c=='a')

    {

        num[numpos] = asin(num[numpos]);

    }

    else if(c=='c')

    {

        num[numpos] = cos(num[numpos]);

    }

    else if(c=='b')

    {

        num[numpos] = acos(num[numpos]);

    }

    else if(c=='t')

    {

        num[numpos] = tan(num[numpos]);

    }

    else if(c=='d')

    {

        num[numpos] = atan(num[numpos]);

    }

    else if(c=='u')

    {

        num[numpos] = num[numpos]*3.14159265358/180;

    }

    else if (c == '!')

    {

        long sum=1;

        int nums=num[numpos];

        for(int i=2;i<=nums;++i)

        {

            sum*=i;

        }

        num[numpos] =sum;

    }

    else

    {

        merge(&num[numpos - 1], num[numpos], c);

        --numpos;

    }

}

std::string qiuzhi(const char *bds)

{

    std::ofstream suffix;

    suffix.open("suffix.txt",std::ios::out|std::ios::binary|std::ios::app);

    int i = 0;

        stack *ysf = (stack*)malloc(sizeof(stack));//为表达式开辟一个stack

        ysf->size = 0;

        double num[50] ;//用于求值的数组

        int numpos = 0;//用于求值的数组位置//ps因为num这个栈用的操作非常的少,而stack没有泛化,所以没有采用栈

        while (bds[i] != '=')

        {

            if (bds[i] <= '9'&&bds[i] >= '0')//为数字的情况,转换为1个数,如234

            {

                num[++numpos] = 0;

                while (bds[i] <= '9'&&bds[i] >= '0')

                {

                    num[numpos] *= 10;

                    num[numpos] += (bds[i] - '0');

                    ++i;

                }

                if (bds[i] == '.')

                {

                    double f_car=0.1;//定义基数

                    ++i;

                    while (bds[i] <= '9'&&bds[i] >= '0')

                    {

                        num[numpos] += ((bds[i] - '0')*f_car);

                        f_car *= 0.1;

                        ++i;

                    }

                }//计算小数点

                suffix<<num[numpos]<<' ';

            }

            else if(bds[i]=='('&&bds[i+1]=='-')

            {

                i+=2;

                num[++numpos] = 0;

                while (bds[i] <= '9'&&bds[i] >= '0')

                {

                    num[numpos] *= 10;

                    num[numpos] += (bds[i] - '0');

                    ++i;

                }

                if (bds[i] == '.')

                {

                    double f_car=0.1;//定义基数

                    ++i;

                    while (bds[i] <= '9'&&bds[i] >= '0')

                    {

                        num[numpos] += ((bds[i] - '0')*f_car);

                        f_car *= 0.1;

                        ++i;

                    }

                }//计算小数点

                num[numpos]*=-1;

                suffix<<num[numpos]<<' ';

                i+=1;

            }//

            else if(bds[i]=='p')

            {

                num[++numpos]=3.14159265358;

                 suffix<<"Π"<<' ';

                ++i;

            }

            else if(bds[i]=='e')

            {

                num[++numpos]=2.71828182845;

                suffix<<'e'<<' ';

                ++i;

            }

            else

            {

 

               if (empty(ysf))//栈为空的情况

                    push(ysf, bds[i]);

                else

                {

                    if (bds[i] == '(')

                        push(ysf, bds[i]);

                    else if (bds[i] == ')')//右括号的情况

                    {

                        while (top(ysf) != '(')

                        {

                            operat(num,numpos,top(ysf));//调用对数据运算的函数

                            suffix<<char_change(top(ysf))<<' ';

                           pop(ysf);

                        }

                        pop(ysf);//弹出右括号

                    }

                    else

                    {

                        while (compare(bds[i])<=compare(top(ysf)))//优先级映射函数

                        {

                            operat(num,numpos,top(ysf));

                          suffix<<char_change(top(ysf))<<' ';

                             pop(ysf);

                        }

                        push(ysf, bds[i]);

                    }

                }

                ++i;

            }

        }

        while (!empty(ysf))//最后的出栈

        {

             operat(num,numpos,top(ysf));

              suffix<<char_change(top(ysf))<<' ';

             pop(ysf);

        }

        suffix<<'\n';

        suffix.close();

        std::stringstream ss;

           ss<<num[1];

           free (ysf);

           return ss.str();

}

dialog.h

  #ifndef DIALOG_H

#define DIALOG_H

#include <QDialog>

#include<string>

namespace Ui {

class Dialog;

}

 

class Dialog : public QDialog

{

    Q_OBJECT

    std::string bds;//用于运算的bds

    QString out_bds;//用于输出的bds

public:

    void init_();//对图形界面预处理

    explicit Dialog(QWidget *parent = nullptr);

    QString string_change(std::string s);//把表达式转化为输出的表达式

    ~Dialog();

 

private slots:

 

   void on_pushButton_sin_clicked();

 

   void on_pushButton_2nd_clicked();

 

   void on_pushButton_rad_clicked();

 

   void on_pushButton_cos_clicked();

 

   void on_pushButton_tan_clicked();

 

   void on_pushButton_pow_clicked();

 

   void on_pushButton_lg_clicked();

 

   void on_pushButton_left_clicked();

 

   void on_pushButton_ln_clicked();

 

   void on_pushButton_right_clicked();

 

   void on_pushButton_sqrt_clicked();

 

   void on_pushButton_ac_clicked();

 

   void on_pushButton_del_clicked();

 

   void on_pushButton_div_clicked();

 

   void on_pushButton_mul_clicked();

 

   void on_pushButton_fac_clicked();

 

   void on_pushButton_num7_clicked();

 

   void on_pushButton_num8_clicked();

 

   void on_pushButton_num9_clicked();

 

   void on_pushButton_sub_clicked();

 

   void on_pushButton_rec_clicked();

 

   void on_pushButton_num4_clicked();

 

   void on_pushButton_num5_clicked();

 

   void on_pushButton_num6_clicked();

 

   void on_pushButton_add_clicked();

 

   void on_pushButton_pi_clicked();

 

   void on_pushButton_num1_clicked();

 

   void on_pushButton_num2_clicked();

 

   void on_pushButton_num3_clicked();

 

   void on_pushButton_equal_clicked();

 

   void on_pushButton_e_clicked();

 

   void on_pushButton_per_clicked();

 

   void on_pushButton_num0_clicked();

 

   void on_pushButton_point_clicked();

 

   void on_textBrowser_textChanged();

 

private:

    Ui::Dialog *ui;

};

 

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

#include "ui_dialog.h"

#include<bds_qz.h>

Dialog::Dialog(QWidget *parent) :

    QDialog(parent),

    ui(new Ui::Dialog)

{

    ui->setupUi(this);

       init_();

}

 

Dialog::~Dialog()

{

    delete ui;

}

void Dialog::init_()

{//ui->textBrowser->setStyleSheet("QTextBrowser{border-width:0;border-style:outset}");

     ui->textBrowser->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    ui->textBrowser->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//关闭滚动条

   // ui->pushButton_2nd->setFlat(true);

}

   QString Dialog:: string_change(std::string s)

  {

   int i=0;

  std:: string new_bds;

   while(s[i]!='\0')

   {

       new_bds+=char_change(s[i]);

       ++i;

   }

    QString qn_bds=QString(QString::fromLocal8Bit(new_bds.c_str()));

    return qn_bds;

   }

void Dialog::on_pushButton_sin_clicked()

{

    if(ui->pushButton_sin->text()=="sin")

   { bds+='s';

      ui->textBrowser->insertHtml("sin");}

    else

    {

        bds+='a';

    ui->textBrowser->insertHtml("arcsin");}

}

 

void Dialog::on_pushButton_2nd_clicked()

{

if(ui->pushButton_sin->text()=="sin")

{ui->pushButton_sin->setText("arcsin");

    ui->pushButton_cos->setText("arccos");

        ui->pushButton_tan->setText("arctan");

}

else

{

    ui->pushButton_sin->setText("sin");

     ui->pushButton_cos->setText("cos");

     ui->pushButton_tan->setText("tan");

}

}

 

void Dialog::on_pushButton_rad_clicked()

{

    bds+='u';

    QString str = QString::fromLocal8Bit("°");//为了显示中文的°

 ui->textBrowser->insertHtml(str);

}

 

void Dialog::on_pushButton_cos_clicked()

{

    if(ui->pushButton_sin->text()=="sin")

   { bds+='c';

      ui->textBrowser->insertHtml("cos");}

    else

    {

        bds+='b';

    ui->textBrowser->insertHtml("arccos");}

}

 

void Dialog::on_pushButton_tan_clicked()

{

    if(ui->pushButton_sin->text()=="sin")

   { bds+='t';

      ui->textBrowser->insertHtml("tan");}

    else

    {

        bds+='d';

    ui->textBrowser->insertHtml("arctan");}

}

 

void Dialog::on_pushButton_pow_clicked()

{

    bds+='^';

    ui->textBrowser->insertHtml("^");

}

 

void Dialog::on_pushButton_lg_clicked()

{

    bds+='g';

    ui->textBrowser->insertHtml("lg");

}

 

void Dialog::on_pushButton_left_clicked()

{

    bds+='(';

    ui->textBrowser->insertHtml("(");

}

 

void Dialog::on_pushButton_ln_clicked()

{

    bds+='n';

    ui->textBrowser->insertHtml("ln");

}

 

void Dialog::on_pushButton_right_clicked()

{

    bds+='c';

    ui->textBrowser->insertHtml("cos");

}

 

void Dialog::on_pushButton_sqrt_clicked()

{

    bds+='v';

     QString str = QString::fromLocal8Bit("√");

ui->textBrowser->insertHtml(str);

}

 

void Dialog::on_pushButton_ac_clicked()

{

    if(!bds.empty())

    { int  star=0;

     if(bds[bds.length()-1]!='\n')//如果不是下一行的话

      {for(int i=0;bds[i]!='\0';++i)

      {if(bds[i]=='\n')

              star=i+1;}}

     else

            {  for(int i=0;bds[i]!='\r';++i)

                  if(bds[i]=='\n')

                      star=i+1;   }

      bds.erase(star);

      QString s=string_change(bds);

    ui->textBrowser->setPlainText(s);}

}

 

void Dialog::on_pushButton_del_clicked()

{

    if(!bds.empty())

   { int bds_end=bds.length()-1;

    if(bds[bds_end]!='\n')

    bds.erase(bds.length()-1);//如果不是上一行的话就删除一个字符

   //QString s= QString::fromStdString(bds);

  QString s=string_change(bds);

ui->textBrowser->setPlainText(s);}

}

 

void Dialog::on_pushButton_div_clicked()

{

    bds+='/';

    QString str = QString::fromLocal8Bit("÷");

    ui->textBrowser->insertHtml(str);

}

 

void Dialog::on_pushButton_mul_clicked()

{

    bds+='*';

    QString str = QString::fromLocal8Bit("x");

    ui->textBrowser->insertHtml(str);

}

 

void Dialog::on_pushButton_fac_clicked()

{

    bds+='!';

    ui->textBrowser->insertHtml("!");

}

 

void Dialog::on_pushButton_num7_clicked()

{

    bds+='7';

    ui->textBrowser->insertHtml("7");

}

 

void Dialog::on_pushButton_num8_clicked()

{

    bds+='8';

    ui->textBrowser->insertHtml("8");

}

 

void Dialog::on_pushButton_num9_clicked()

{

    bds+='9';

    ui->textBrowser->insertHtml("9");

}

 

void Dialog::on_pushButton_sub_clicked()

{

    bds+='-';

    ui->textBrowser->insertHtml("-");

}

 

void Dialog::on_pushButton_rec_clicked()

{

    bds+="^(-1)";

    ui->textBrowser->insertHtml("^(-1)");

}

 

void Dialog::on_pushButton_num4_clicked()

{

    bds+='4';

    ui->textBrowser->insertHtml("4");

}

 

void Dialog::on_pushButton_num5_clicked()

{

    bds+='5';

    ui->textBrowser->insertHtml("5");

}

 

void Dialog::on_pushButton_num6_clicked()

{

    bds+='6';

    ui->textBrowser->insertHtml("6");

}

 

void Dialog::on_pushButton_add_clicked()

{

    bds+='+';

    ui->textBrowser->insertHtml("+");

}

 

void Dialog::on_pushButton_pi_clicked()

{

    bds+='p';

    ui->textBrowser->insertHtml("Π");

}

 

void Dialog::on_pushButton_num1_clicked()

{

    bds+='1';

    ui->textBrowser->insertHtml("1");

}

 

void Dialog::on_pushButton_num2_clicked()

{

    bds+='2';

    ui->textBrowser->insertHtml("2");

}

 

void Dialog::on_pushButton_num3_clicked()

{

    bds+='3';

    ui->textBrowser->insertHtml("3");

}

 

void Dialog::on_pushButton_equal_clicked()

{

    bds+='=';

    const char *c_bds=bds.data();

     std::string result=qiuzhi(c_bds);

     bds+=result;

     bds+="\r\n";

     bds+=result;

    QString qresult=QString::fromStdString(result);

    ui->textBrowser->insertHtml("=");

     ui->textBrowser->insertHtml(qresult);

      ui->textBrowser->insertHtml("<br>");

      ui->textBrowser->insertHtml(qresult);

}

 

void Dialog::on_pushButton_e_clicked()

{

    bds+='e';

    ui->textBrowser->insertHtml("e");

}

 

void Dialog::on_pushButton_per_clicked()

{

    bds+='%';

    ui->textBrowser->insertHtml("%");

}

 

void Dialog::on_pushButton_num0_clicked()

{

    bds+='0';

    ui->textBrowser->insertHtml("0");

}

 

void Dialog::on_pushButton_point_clicked()

{

    bds+='.';

    ui->textBrowser->insertHtml(".");

}

 

void Dialog::on_textBrowser_textChanged()

{

     ui->textBrowser->moveCursor(QTextCursor::End);

}

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt是一个跨平台的应用程序开发框架,提供了丰富的库和工具,用于开发图形用户界面和其他应用程序。Qt Widget是Qt框架中的一个模块,用于创建和管理图形界面元素,如窗口、按钮、输入框等。 在Qt中,使用Widget编写一个简单的例程非常简单。首先,我们需要创建一个Qt Widget项目。然后,在主窗口中添加各种需要的控件,例如按钮、文本框等。接下来,可以通过设各个控件的属性和信号槽来实现交互逻辑。最后,编译并运行程序,即可看到创建的窗口和控件。 例如,我们可以编写一个计算器的例程。首先,在主窗口中放一些按钮和一个文本框,用于输入和显示计算结果。然后,编写相应的函数来实现按钮的点击事件。例如,当用户点击数字按钮时,将该数字添加到文本框中;当用户点击运算符按钮时,将运算符添加到文本框中。最后,编写一个计算函数来实现实际的计算逻辑,将计算结果显示到文本框中。 通过以上步骤,我们就可以完成一个简单Qt Widget例程。当用户运行程序时,会出现一个计算器界面,可以进行简单的数学运算。这只是一个简单的示例,Qt Widget可以用于开发各种类型的应用程序,例如文本编辑器、图像处理工具等。 总之,Qt Widget是Qt框架中用于创建图形用户界面的模块,通过添加控件、处理事件和信号槽来实现交互逻辑,可以用于开发各种功能丰富的应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值