• 面向对象程序设计__Task6_Calculator1.6.2


    The 4th part of the Calculator program _ Interface

    题目链接:第六次作业(计算器第四步)
    github链接:Calculator_1.6.2 第六次作业
    工具:Qt Creator 5.6.0

    讲道理好吧,终于有界面啦= =!!!还是先来说说上次的作业。第五次作业在完成之后各种缝缝补补(版本更迭!1.5.xxx),最大的问题就是偷懒的Scan.cpp里面读取表达式时遗留下来的坑。虽然之后线下自己做了修改,加上了些预处理,但是看到第五次作业结果惨不忍睹的正确率时,内心还是有点小崩溃的(早知道早点改了),另外Printer类的输出方法还是有点乱,各种调用有点理不清。

    然后就是这次的作业,界面!version 1.6.2!

    一开始是QT和MFC的选择,在各种百度之后,想想就短短几天,果断选择了简单方便的QT,虽然可能MFC不失为更好的选择...

    接下来就是Qt的各种尝试历程

    Part 1

    在经过简单的Qt学习之后,就直接开始征程了。一开始,当然是恬不知耻(hhh~)的开启ui设计模式,各种拖动框框,东拼西凑,欧啦,一个纸面上的界面就完成啦!

    接着只要对每一个按钮设置槽,再将第五次作业的各种类导入,当当当当,一个简单的计算器v1.6.0,Over~

    Part 2

    看完Part 1简单的两段话,是不是觉得步骤太过简单了= =,别急,下面就是不用ui文件这种粗暴的做法,而是代码的实现。

    Calculator.h

    class Calculator : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit Calculator(QWidget *parent = 0);
        ~Calculator();
    protected:
        FileOperation *fo;
        Printer *pr;
    
        QLineEdit *editLine;     // 输入框
        QLabel *answerLine;      // 结果框
        // 按钮
        QPushButton *button_0, *button_1, *button_2, *button_3, *button_4, *button_5, *button_6
            , *button_7, *button_8, *button_9;
        QPushButton *button_point, *button_add, *button_sub, *button_mul, *button_div, *button_equal;
        QPushButton *button_lBracket, *button_rBracket;
        QPushButton *button_file, *button_clear, *button_del;
        string inputExp;
        QString showAnswer;
        double cacheAnswer;
        bool equalFlag;     // 是否已按下等号
    private:
        Ui::Calculator *ui;
    private slots:
        void button_0_clicked();     // 槽
        void button_1_clicked();
        void button_2_clicked();
        void button_3_clicked();
        void button_4_clicked();
        void button_5_clicked();
        void button_6_clicked();
        void button_7_clicked();
        void button_8_clicked();
        void button_9_clicked();
        void button_point_clicked();
        void button_add_clicked();
        void button_sub_clicked();
        void button_mul_clicked();
        void button_div_clicked();
        void button_equal_clicked();
        void button_file_clicked();
        void button_clear_clicked();
        void button_del_clicked();
        void button_lBracket_clicked();
        void button_rBracket_clicked();
    };
    

    Calculator.cpp

    Calculator::Calculator(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::Calculator)
    {
        ui->setupUi(this);
        this->setWindowTitle(QStringLiteral("计算器"));
        this->setFixedSize(300, 230);
        this->setStyleSheet("background-image:url(D:/Qt_Creator_Projects/Calculator_2/bg_6.jpg)");
    
        fo = NULL;
        pr = new Printer();
    
        cacheAnswer = 0;
        equalFlag = false;
        editLine = new QLineEdit("0");
        ...
        button_add->setFixedSize(51, 56);
        button_file->setToolTip(QStringLiteral("文件读写操作"));
        button_clear->setFixedSize(51, 56);
    
        QGridLayout *mainLayout = new QGridLayout(this);
        mainLayout->addWidget(editLine, 0, 0, 1, 5);     // 布局
    	...
    
        connect(button_0, SIGNAL(clicked()), this, SLOT(button_0_clicked()));
        ...
    
        setLayout(mainLayout);
    
    }
    
    void Calculator::button_0_clicked()
    {
       if (editLine->text() == "0" || equalFlag)
       {
           if (equalFlag)
           {
               equalFlag = false;
           }
           editLine->setText(QString('0'));
       }
       else
       {
           editLine->setText(editLine->text() + QString('0'));
       }
    }
    
    ...
    
    void Calculator::button_add_clicked()
    {
        if (equalFlag)
        {
            equalFlag = false;
            editLine->setText(showAnswer);
        }
        editLine->setText(editLine->text() + QString('+'));
    }
    
    ...
    
    void Calculator::button_equal_clicked()
    {
        if (equalFlag)
        {
            editLine->setText(QString('0'));
        }
        else
        {
            answerLine->setText(editLine->text() + QString(" = "));
            editLine->setText(editLine->text() + QString('='));
            inputExp = editLine->text().toStdString();
            cacheAnswer = pr->printResult(inputExp);
            showAnswer = QString::number(cacheAnswer, 10, 12);     // 默认至多保留12位小数
            int pointIndex = showAnswer.indexOf(".");
            bool afterPointNonZeroInt = false;     // 小数点后是否存在非零整数
            int afterPointFirstNonZeroIntIndex = pointIndex;
            for (int i = pointIndex; i < showAnswer.length(); i++)
            {
                if (showAnswer[i] >= '1' && showAnswer[i] <= '9')
                {
                    afterPointNonZeroInt = true;
                    afterPointFirstNonZeroIntIndex = i;
                    break;
                }
            }
            int precision = showAnswer.indexOf("0", afterPointFirstNonZeroIntIndex);
            if (precision != -1 && precision > pointIndex)
            {
                if (!afterPointNonZeroInt)     // 若为整数(.000....),则截取至(不含)小数点
                {
                    showAnswer = showAnswer.left(pointIndex);
                }
                else
                {
                    showAnswer = showAnswer.left(precision);
                }
            }
            answerLine->setText(answerLine->text() + showAnswer);
        }
        equalFlag = true;
    }
    
    void Calculator::button_file_clicked()
    {
        fo = new FileOperation();
        fo->show();
    }
    
    void Calculator::button_clear_clicked()
    {
        editLine->setText(QString('0'));
        answerLine->setText(QString('0'));
    }
    
    void Calculator::button_del_clicked()
    {
        if (equalFlag)
        {
            equalFlag = false;
            editLine->setText(QString('0'));
            answerLine->setText(QString('0'));
        }
        else
        {
            QString qs = editLine->text();
            int len = qs.length();
            if (len == 1)
            {
                editLine->setText(QString('0'));
            }
            else
            {
                editLine->setText(qs.left(len - 1));
            }
        }
    }
    

    眼花缭乱有没有!想砸了它有没有!要多少个按钮就定义了多少个PushButton和槽!

    不过程序还是不难理解的。按下按钮后对应显示区显示对应符号,在deadline更新到5号之后,多出来的两天也让我有时间将自己的想法多修修补补,比如,"="按下后,在v1.6.1中是固定显示3位小数的,包括"x.000","x.xxx(xxx...万分位开始被截断)"的情况,后来在v1.6.2中改进,寻找最佳的精度(默认至多不超过12位小数)并显示到显示区。再如,v1.6.2比起v1.6.1也加上了图标、背景等等。

    Part 3

    在Calculator中,File按钮对应的是打开文件操作窗口,即第五次作业所要求的文件读写,该部分写在FileOperation类中

    FileOperation.h

    class FileOperation : public QDialog
    {
        Q_OBJECT
    public:
        explicit FileOperation(QWidget *parent = 0);
        ~FileOperation();
    protected:
        Printer *pr;
        QLabel *input_1;
        QLabel *input_2;
        QLineEdit *inputAddrLine;
        QLineEdit *outputAddrLine;
        QPushButton *findAddr_1;
        QPushButton *findAddr_2;
        QPushButton *finish;
        QPushButton *cancel;
        string inputAddr;
        string outputAddr;
    signals:
        void clicked();
    private slots:
        void findAddr_1_clicked();
        void findAddr_2_clicked();
        void finish_clicked();
        void cancel_clicked();
    };
    

    FileOperation.cpp

    FileOperation::FileOperation(QWidget *parent) :
        QDialog(parent)
    {
        this->setWindowTitle(QStringLiteral("文件读写操作"));
        this->setFixedSize(250, 150);
        this->setStyleSheet("background-image:url(D:/Qt_Creator_Projects/Calculator_2/bg_6.jpg)");
    
        pr = new Printer();
        input_1 = new QLabel("the input file address :");
    	...
        findAddr_1->setToolTip(QStringLiteral("选择输入文件路径"));
        findAddr_2->setToolTip(QStringLiteral("选择输出文件路径"));
        QGridLayout *fileDialogLayout = new QGridLayout(this);
        fileDialogLayout->addWidget(input_1, 0, 0, 1, 4);
        ...
    
        connect(findAddr_1, SIGNAL(clicked()), this, SLOT(findAddr_1_clicked()));
        ...
    
        setWindowFlags(Qt::WindowStaysOnTopHint);
        setLayout(fileDialogLayout);
    }
    
    void FileOperation::findAddr_1_clicked()
    {
        QString fil = QFileDialog::getOpenFileName(this, tr("Open txt"), ".", tr("txt Files(*.txt)"));
        inputAddrLine->setText(fil);
    }
    
    void FileOperation::findAddr_2_clicked()
    {
        QString fil = QFileDialog::getOpenFileName(this, tr("Open txt"), ".", tr("txt Files(*.txt)"));
        outputAddrLine->setText(fil);
    }
    
    void FileOperation::finish_clicked()
    {
        inputAddr = inputAddrLine->text().toStdString();
        outputAddr = outputAddrLine->text().toStdString();
        if (inputAddr.empty() || outputAddr.empty())
        {
            cout << "无效地址" << endl;
        }
        else
        {
            pr->printResult_f(inputAddr, outputAddr);
        }
        this->close();
    }
    
    void FileOperation::cancel_clicked()
    {
        this->close();
    }
    

    一个简单的文件操作界面就完成了,v1.6.1测试时发现当有文件路径为空时,点finished程序会gg,在v1.6.2的时候也做了简单的处理

    Part 4

    那么再说说这次的Qt之旅上的问题,除了上面涉及的之外,还有一点就是乱码的问题,百度上众云纷说,最后发现Qt5的QStringLiteral(const char*),用来从“字符串常量”创建QString对象的宏,避免了各种编码转换带来的乱码的问题。

    再来就是qmake这玩意,并不是很理解,但有一点是,有时候你在往你的项目中添加文件时,没有加到项目中(有点懵逼...),导致出现无法解析的外部符号的error,再重新qmake之后,瞬间构建成功了。

    还有就是遗留的Printer类的调用问题,加上暂未实现的提示对话框...等等等等

    Part 5

    这次的Qt的学习收获还是挺大的,对一个新的东西先有了大概上的了解,再加之以应用,总是能学到很多,当蹦出来的红色的error一个个消散时,当总算蹦出一个稍微能看点的界面时,总还是很激动的。

    另外,感觉这次稍微多出来了点的时间,让自己闲着没事时不时想到了一些想法也能加以尝试、实现,再一次在自己的代码上不断的改进,看着它一点一点的改善也是有点小happy,而改进之路上遇到的新的问题,更多依靠百度加以理解最后解决。

    毕竟,一路百度,一路前行(2333...)

    最后,就不贴参考博客什么的了(毕竟问题太多参考得也多...),只附上运行图:

    计算器运行图_1

    计算器运行图_2

    计算器运行图_3

    计算器运行图_4

    The End

  • 相关阅读:
    CDH5.2安装更换hive元数据存储数据库遇到的问题
    SSH 互信
    【记录】Java NIO实现网络模块遇到的BUG
    Http2协议简介
    synchronized(this) 与 synchronized(class) 理解
    【记录】spring boot 图片上传与显示
    Cookie-Session机制
    linux利用用户组给用户赋予不同的权限
    java .equals()和==的区别
    String直接赋值和使用new的区别
  • 原文地址:https://www.cnblogs.com/monsterJang/p/5561089.html
Copyright © 2020-2023  润新知