Qt练手——计算圆面积和计算器(不含括号)

本文介绍了作者为准备校招Qt岗位而重新制作的两个项目:计算圆面积APP(first)和仿计算器APP(second)。first项目通过用户输入圆的半径,利用UI设计计算并显示面积;second项目则使用QGridLayout布局和Q GridLayout实现计算器功能,包括加减乘除。代码中详细展示了类和函数的设计,特别是逆波兰表达式的计算逻辑。项目源码已上传至GitHub供参考。
摘要由CSDN通过智能技术生成

序言

为了下学期校招单位的Qt岗,我将我大一做过的两个项目又拿出来重做了下,分别是计算圆面积APP和仿计算器APP。这个计算器是不含括号的但是有优先级的,基本原理就是先转为逆波兰表达式,再计算结果。计算圆面积APP被命名为first而仿计算器APP命名为second,first用的是UI设计的,即拖动相应的部件并调整大小;而second使用的是布局管理器(QGridLayout)来实现的,纯代码类型。

现在来看项目first。


圆面积计算APP(项目名:first)

结果展示

具体思路

它的主要想法是输入圆的半径R,通过圆面积公式S=\pi \times R^{2}来计算面积S。全部文件如下所示:

类名为dialog主要的逻辑公式写在dialog.cpp中如下所示:

void Dialog::on_countBtn_clicked()
{
    bool ok;
    QString tempStr;
    QString valueStr=ui->radiusLineEdit->text();//传过来的信号(半径R)
    int valueInt=valueStr.toInt(&ok);//将字符串R转为数字
    double area=valueInt*valueInt*3.14159;//逻辑计算
    ui->radiusLabel->setText(tempStr.setNum(area));//返回给槽
}

 on_countBtn_clicked函数定义在类Dialog中,是一个private slots,类Dialog如下所示:

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();

private slots:

    void on_countBtn_clicked();//计算按钮

private:
    Ui::Dialog *ui;
};

 这个APP比较简单,也不涉及什么算法。只有dialog.h和dialog.cpp需要修改小小的两个地方。下面来看第二个项目。

仿计算器APP(项目名:second)

结果展示

项目结构

具体思路

使用了布局管理器(QGridLayout)一行4个空,一共5行。用了三个label和12个button ,C键是clear的意思,直接作清空操作。该项目的类名也叫second,second类定义如下所示:

class second : public QWidget {
Q_OBJECT

public:
    QString h="";//h用于存放当前的式子
    explicit second(QWidget *parent = nullptr);

    ~second() override;

private:
    Ui::second *ui;
    //定义各个部件
    QLabel *text_content, *answer, *question;
    QPushButton *cal,*one,*two,*three,*four,*five,*six,*seven,*eight,*nine,*zero,*clear,*plus,*minus,*cheng,*chu;


private slots:
    //计算的核心函数,具体定义在second.cpp中
    void CAL();
    //为了方便,就不在second.cpp中定义了,但这是不规范的。
    //用于定义每个按钮的行为,对应哪个按钮从函数名就可以看出。
    void One()
    {
        h+='1';
        question->setText(h);
    };
    void Two()
    {
        h+='2';
        question->setText(h);
    };
    void Three()
    {
        h+='3';
        question->setText(h);
    };
    void Four()
    {
        h+='4';
        question->setText(h);
    };
    void Five()
    {
        h+='5';
        question->setText(h);
    };
    void Six()
    {
        h+='6';
        question->setText(h);
    };
    void Seven()
    {
        h+='7';
        question->setText(h);
    };
    void Eight()
    {
        h+='8';
        question->setText(h);
    };
    void Nine()
    {
        h+='9';
        question->setText(h);
    };
    void Zero()
    {
        h+='0';
        question->setText(h);
    };
    void Plus()
    {
        h+='+';
        question->setText(h);
    };
    void Minus()
    {
        h+='-';
        question->setText(h);
    };
    void Cheng()
    {
        h+='*';
        question->setText(h);
    };
    void Chu()
    {
        h+='/';
        question->setText(h);
    };
    void Clear()
    {
        h="";
        question->setText(h);
    };

};

接着我要在second.cpp中写上面那个CAL函数的逻辑,及计算逆波兰表达式的函数,其中还有一个change函数,用于计算出逆波兰表达式,而CAL则是计算逆波兰表达式的结果。具体逻辑如下:

//手撕单链表用于表示栈stack,没有用STL。
//定义结点
struct node
{
    double data;
    node *next;
public:
    node();
};

node::node() {}

//定义栈
class stack
{
private:
    node* top;
public:
    stack() { top = NULL; }//初始化,构造函数
    ~stack();
    void push(double e);//入栈操作
    double pop();//退栈操作
    double getTop();//取顶部操作
    bool isEmpty() { if (top == NULL) return true; else return false; }//判空操作
};

double stack::getTop()
{
    if (top != NULL)
        return top->data;
}

stack::~stack()
{
    node* p;
    while (top)
    {
        p = top->next;
        delete top;
        top = p;
    }
}

void stack::push(double e)
{
    node* p = new node;
    if (!p)
    {
        //cout << "内存分配失败" << endl;
        return;
    }
    p->data = e;
    p->next = top;
    top = p;
}

double stack::pop()
{
    if (top == NULL)
    {
        //cout << "溢出" << endl;
    }
    double temp = top->data;
    node* p = top;
    top = top->next;
    delete p;
    return temp;
}

struct Node
{
    double data;
    Node *next;
};
class sqqueue
{
private:
    Node *front;
    Node *rear;
public:
    sqqueue();
    ~sqqueue();
    void enqueue(double e);
    double dequeue();
    bool isEmpty();
    double getFront();
};

double sqqueue::getFront()
{
    return front->next->data;
}

sqqueue::sqqueue()
{
    front = new Node;
    front->next = NULL;
    rear = front;
}

sqqueue::~sqqueue()
{
    Node *p=NULL;
    while (front != NULL)
    {
        p = front;
        front = front->next;
        delete p;
    }
}

void sqqueue::enqueue(double e)
{
    Node *s = new Node;
    s->data = e;
    s->next = rear->next;
    rear->next = s;
    rear = s;
    if (front->next == NULL)
        front->next = s;
}

double sqqueue::dequeue()
{
    double e;
    Node *p = NULL;
    if (rear == front)
    {
        //cout << "下溢" << endl;
    }
    p = front->next;
    e = p->data;
    front->next = p->next;
    if (p->next == NULL)
        rear = front;
    delete p;
    return e;
}

sqqueue output;
stack s;
stack a;

//计算出具体的逆波兰表达式
void change(std::string str)
{
    double num;
    double temp;
    for (int i = 0; i < str.length();)
    {
        if (str[i] >= '0'&&str[i] <= '9')
        {
            temp = str[i++] - '0';
            while (i < str.length() && str[i] >= '0'&&str[i] <= '9')
            {
                temp = temp * 10 + (str[i] - '0');
                i++;
            }
            output.enqueue(temp);
        }
        else
        {
            if (((str[i] == '+' || str[i] == '-')&&(s.getTop() == -3|| s.getTop() == -4))|| ((str[i] == '+' || str[i] == '-') && (s.getTop() == -1 || s.getTop() == -2))|| ((str[i] == '*' || str[i] == '/') && (s.getTop() == -3 || s.getTop() == -4)))
            {
                while (!s.isEmpty())
                {
                    output.enqueue(s.pop());
                }
            }
            switch (str[i])
            {
            case '+':s.push(-1); break;
            case '-':s.push(-2); break;
            case '*':s.push(-3); break;
            case '/':s.push(-4); break;
            default:break;
            }
            i++;
        }
    }
    while (!s.isEmpty())
    {
        output.enqueue(s.pop());
    }
}

//计算逆波兰表达式的结果
void second::CAL()
{
    QString valueStr;
    QString tempStr=question->text();//获取信号
    std::string str=tempStr.toStdString();//将Qt的Qstring转化为string(C++标准的)
    change(str);
    double temp;
    double r, l;
    while (!output.isEmpty())
    {
        if (output.getFront() >= 0)
        {
            a.push(output.dequeue());
        }
        else
        {
            double x = output.dequeue();
            if (x == -1)
            {
                r = a.pop();
                l = a.pop();
                temp = l + r;
                a.push(temp);
            }
            else if (x == -2)
            {
                r = a.pop();
                l = a.pop();
                temp = l - r;
                a.push(temp);
            }
            else if (x == -3)
            {
                r = a.pop();
                l = a.pop();
                temp = l * r;
                a.push(temp);
            }
            else if (x == -4)
            {
                r = a.pop();
                l = a.pop();
                temp = l / r;
                a.push(temp);
            }
        }
    }
    double ans=a.pop();
    answer->setText(valueStr.setNum(ans));//传给槽
}

具体的项目可以看我的Github,这是地址: https://github.com/timTianWSRF/Qt_calculator-tim-

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TIM33470348

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值