Qt--计算器的实现

一.计算机程序界面分析

从效果图我们可以得知
1.QLineEdit用于接受用户输入
2.QLineEdit能够获取用户输入的字符串
3.QLineEdit是功能性组件,需要父组件作为容器
4.QLineEdit能够在父组件中进行定位
该计算器的坐标及位置如图所示

界面的代码实现

#include "Widget.h"
#include <QApplication>
#include <QPushButton>
#include <QLineEdit>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget* w = new QWidget(NULL, Qt::WindowCloseButtonHint);
    w->setWindowTitle("Calculator");
    QLineEdit* le = new QLineEdit(w);
    QPushButton* button[20] = {0};
    const char* btnText[20] =
    {//数字键与功能键
         "7", "8", "9", "+", "(",
         "4", "5", "6", "-", ")",
         "1", "2", "3", "*", "<-",
         "0", ".", "=", "/", "C",
    };
    int ret = 0;
    //设置的大小以及坐标
    le->move(10, 10);
    le->resize(240, 30);
    le->setReadOnly(true);
    //数字键与功能键的位置的实现
    for(int i=0; i<4; i++)
    {
         for(int j=0; j<5; j++)
         {
             button[i*5 + j] = new QPushButton(w);
             button[i*5 + j]->resize(40, 40);
             button[i*5 + j]->move(10 + (10 + 40)*j, 50 + (10 + 40)*i);
             button[i*5 + j]->setText(btnText[i*5 + j]);
         }
    }

    w->show();
    w->setFixedSize(w->width(), w->height());

    ret = a.exec();

    delete w;

    return ret;
}

运行的结果如图所示

上面只是暂时生成了计算机demo的UI,会存在许多的问题以及算法的实现按会在接下来进行介绍
A.计算器界面的代码重构
1.重构--以改善代码质量为目的代码重写,使其软件设计的设计和架构更加合理,提高软件的扩展性和维护性
代码的实现与重构不同
代码实现--按照设计编程实现,重心在于功能的实现
代码重构--以提高代码质量为目的软件架构优化
区别:代码实现是不考虑架构的好坏,只考虑功能的实现,代码重构时不能影响已实现的功能,只考虑架构的改善
计算器界面代码重构

重构的实现

main.cpp
#include "CalculatorUI.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QCalculatorUI* cal = QCalculatorUI::NewInstance();
    int ret = -1;
    if( cal != NULL )
    {
        cal->show();
        ret = a.exec();
        delete cal;
    }
    return ret;
}

CalculatorUI.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLineEdit>
#include <QPushButton>

class QCalculatorUI : public QWidget
{
private:
    QLineEdit* m_edit;
    QPushButton* m_buttons[20];

    QCalculatorUI();
    bool construct();
public:
    static QCalculatorUI* NewInstance();
    void show();
    ~QCalculatorUI();
};

#endif // WIDGET_H

CalculatorUI.cpp
#include "CalculatorUI.h"

QCalculatorUI::QCalculatorUI() : QWidget(NULL, Qt::WindowCloseButtonHint)
{

}

bool QCalculatorUI::construct()
{
    bool ret = true;
    const char* btnText[20] =
    {
        "7", "8", "9", "+", "(",
        "4", "5", "6", "-", ")",
        "1", "2", "3", "*", "<-",
        "0", ".", "=", "/", "C",
    };

    m_edit = new QLineEdit(this);

    if( m_edit != NULL )
    {
        m_edit->move(10, 10);
        m_edit->resize(240, 30);
        m_edit->setReadOnly(true);
    }
    else
    {
        ret = false;
    }

    for(int i=0; (i<4) && ret; i++)
    {
        for(int j=0; (j<5) && ret; j++)
        {
            m_buttons[i*5 + j] = new QPushButton(this);

            if( m_buttons[i*5 + j] != NULL )
            {
                m_buttons[i*5 + j]->resize(40, 40);
                m_buttons[i*5 + j]->move(10 + (10 + 40)*j, 50 + (10 + 40)*i);
                m_buttons[i*5 + j]->setText(btnText[i*5 + j]);
            }
            else
            {
                ret = false;
            }
        }
    }

    return ret;
}

QCalculatorUI* QCalculatorUI::NewInstance()
{
    QCalculatorUI* ret = new QCalculatorUI();

    if( (ret == NULL) || !ret->construct() )
    {
        delete ret;
        ret = NULL;
    }

    return ret;
}

void QCalculatorUI::show()
{
    QWidget::show();

    setFixedSize(width(), height());
}

QCalculatorUI::~QCalculatorUI()
{

}

代码实现的结果

B.在这里要对Qt的消息处理做介绍,对之后计算器的操作会有帮助
1.Qt消息模型

Qt封装了具体操作系统的消息机制
Qt遵循经典的GUI消息驱动事件模型

C.Qt定义了与系统消息相关的概念
a.信号--由操作系统产生的消息
b.--程序中的消息处理函数
c.连接--将系统消息绑定到消息处理函数
Qt的消息处理机制


上图从Qt帮助文档中对connect进行查找,connect函数包含了发送对象、消息名、接收对象、接收对象的的成员函数
D.自定义槽
1.只有QObject的子类才能自定义槽
2.定义槽的类必须在声明的最开始处使用Q_OBJECT
3.类中声明槽时需要使用slots关键字
4.槽与所处理的信号在函数签名上必须一致
5.SIGNAL和SLOT所指定的名称中可以包含参数类型,不能包含具体参数名

//在上面的Calculator.h上添加槽函数
private slots:
    void onButtonClicked();
//同时在cpp上将其实现,通过connect函数将其相连
void QCalculatorUI::onButtonClicked()
{
    QPushButton* btn = (QPushButton*)sender();

    qDebug() << "onButtonClicked()";
    qDebug() << btn->text();
}

connect(m_buttons[i*5 + j], SIGNAL(clicked(bool)), this, SLOT(onButtonClicked()));

按钮按下实现的打印结果

E.计算器算法的实现
1.前缀表达式、中缀表达式、后缀表达式的区别
a.前缀表达式--前缀表达式是一种没有括号的算术表达式,与中缀表达式不同的是,其将运算符写在前面,操作数写在后面。为纪念其发明者波兰数学家Jan Lukasiewicz,前缀表达式也称为“波兰式”。例如,- 1 + 2 3,它等价于1-(2+3)。
b.中缀表达式--是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法。与前缀表达式(例:+ 3 4)或后缀表达式(例:3 4 +)相比,中缀表达式不容易被计算机解析,但仍被许多程序语言使用,因为它符合人们的普遍用法。与前缀或后缀记法不同的是,中缀记法中括号是必需的。计算过程中必须用括号将操作符和对应的操作数括起来,用于指示运算的次序。
c.后缀表达式--后缀表达式,又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)
计算器的算法实现
1.将中缀表达式进行数字和运算符的分离
2.将中缀表达式转换为后缀表达式
3.通过后缀表达式计算最终结果

所有要计算的中缀表达式中包含

分离算法的实现--思想:以符号作为标志对表达式中的字符逐个访问


中缀转后缀
中缀表达式转后缀表达式的过程类似编译过程
1.四则运算表达式中的括号必须匹配
2.根据运算符优先级进行转换
3.转换后的表达式中没有括号
4.转换后可以顺序的计算出最终结果
转换过程的实现:a当前元素e为数字对其输出;b当前元素e为运算符,先与栈顶运算符进行优先级比较,当其小于或者等于时将栈顶元素输出,转1,如果大于将栈顶元素e入栈;c当前元素e为左括号进行入栈;d当前元素e为右括号时弹出栈顶元素并输出,直至栈顶元素为左括号,然后将栈顶的左括号从栈中弹出

合法的四则运算表达式中--括号匹配成对出现,左括号必然先于右括号出现

后缀表达式计算
遍历后缀表达式中的数字和运算符--a当前元素为数字进栈;b当前元素为运算符先从栈中弹出右操作数,再从栈中弹出昨操作数;c根据符号进行运算;d将运算结果压入栈中

最后附上完整的代码下载链接https://down.51cto.com/data/2464399

原文地址:https://blog.51cto.com/13475106/2427965

时间: 2024-10-09 21:03:52

Qt--计算器的实现的相关文章

Qt计算器开发(二):信号槽实现数学表达式合法性检查

表达式的合法性 因为我们的计算器不是单步计算的,所以我们可以一次性输入一个长表达式.然而如果用户输入的长表达式不合法的话,那么就会引发灾难.所以有必要对于用户的输入做一个限制. 一些限制举例: 比如,在输入了左括号以后那么接下来,不能输入运算符.此时运算符要是不可用的状态.在输入了右括号以后不能直接输入数字,此时数字键应该是不可用状态.等等此类的. 在这里我使用了信号与槽的方式来实现.点击不同的按钮,会发展出不同的信号.在这之后的事,点击按钮本身无需考虑,这也是信号槽的良好的设计理念造成的效果,

Qt计算器开发(三):运行效果及项目总结

运行效果 工程目录 Counter |--- Counter.pro |--- 头文件 |      |--- aboutdialog.h |      `--- mainwindow.h |--- 源文件 |      |--- aboutdialog.cpp |      |--- main.cpp |      `--- mainwindow.cpp `--- UI文件 |--- aboutdialog.ui `--- mainwindow.ui 总结 项目 这个工程的Ui部分我是直接使用

QT 计算器小程序

1 项目创建: 2 运行效果图 QT版本计算器 mainwindow.h main.cpp mainwindow.cpp mainwindow.ui 文件1   mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow {     Q_OBJECT pu

Qt 计算器界面实现

学习目的: QWidget  QPushbutton  QLineEdit使用. 通过Qt 代码实现一个计算器界面. QWidget窗口组件: QWidget类继承自 QObject 类和QPaintDevice类 QObject 是所有 支持Qt对象模型 的基类 QPaintDevice Qt中所有 可绘制组件 的基类 QWidget能够绘制自己 和处理 用户的输入 QWidget 是Qt所有窗口组件类的父类  QWidget 是所有窗口组件的抽象 Qt中的每个窗口组件都是一个QWidget

QT学习资料收集

几个专栏 Qt学习之路(3):Hello, world!(续) - 豆子空间 - 51CTO技术博客 http://devbean.blog.51cto.com/448512/194137 Qt 学习之路 2 | DevBean's World https://www.devbean.net/category/qt-study-road-2/ 专栏:Qt实战一二三 - 博客频道 - CSDN.NET http://blog.csdn.net/column/details/qshare.html?

Qt版科学计算器

Qt版科学计算器 转载请标明出处:牟尼的专栏 http://blog.csdn.net/u012027907 之前做过<VC版科学计算器>,这也是我学VC++时的第一个大作业,通过科学计算器的开发使用我学到了很多东西,也让我逐渐喜欢上了编程.最近在学习Qt,所以将当时在VC下写过的一些东西在Qt下重写了一遍,其实主要还是与显示等有关的东西需要重写,要使用Qt的显示方式,而其他的核心的算法等都还是使用VC下C++的源码. 下面是Qt版的运行截图: 标准版: 科学版: 头文件中变量和槽的声明: c

利用Qt调用计算器

之前有了第一个项目那么很快就会有第二个 这次 我们来调用 一些系统函数. 就不从头写了. 直接写比较重要的地方,如果又不太懂的地方欢迎小纸条或者参见利用 QT制作一个 helloworld http://www.cnblogs.com/letben/p/5205060.html 1.双击widget.ui到设计界面. 2.拖一个PushButton到中间灰色区域内. 3.右键PushButton在下拉菜单中转到槽. 4.在跳转之后,键入:system.("calc"); 如图: 5.构

qt实现一个简单的计算器

1.计算器的界面如下图所示 dalog.cpp #include "dialog.h" #include "ui_dialog.h" #include<QPushButton> #include<QDebug> #include<QtMath> const char *a; Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->

QT开发(三十)——计算器实例开发

QT开发(三十)--计算器实例开发 一.计算器界面制作 计算器界面需要QWidget组件作为顶层窗口,QLineEdit组件作为输入框,QPsuhButton作为按钮. 界面规划设计如下: #include <QApplication> #include <QWidget> #include <QLineEdit> #include <QPushButton>   int main(int argc, char *argv[]) {     QApplica

后缀表达式实战:Qt制作计算器

导言 相信学过数据结构的人都听说过后缀表达式,就是在学习栈的时候.可能也有很多人实现过这一算法,不过基本上也都是在控制台窗口里用用.相信大家也都用过计算器windows里面的calc.但是有没发现它只能单步计算,而不能一次计算一个表达式.后缀表达式就有了用武之地,可以一次性计算一整个个式子.科技要为生产服务,所以我就实际去做了一个依据后缀表达式的带有图形化界面的计算器. 什么是后缀表达式 后缀表达式又称逆波兰式,用于简化计算数学表达式,是计算器类软件开发的重要理论依据.这部分有两个要点: 中缀表