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...)

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

The End

面向对象程序设计__Task6_Calculator1.6.2的更多相关文章

  1. [.net 面向对象程序设计深入](0) 开篇

    [.net 面向对象程序设计深入](0)开篇        [.net 面向对象编程基础]和 [.net 面向对象程序设计进阶]在15年底写完了,群里也加进来不少热爱学习的小伙伴.让我深切感受到在这个 ...

  2. [.net 面向对象程序设计进阶] (1) 开篇

    [.net 面向对象程序设计进阶] (1) 开篇 上一系列文章<.net 面向对象编程基础>写完后,很多小伙伴们希望我有时间再写一点进阶的文章,于是有了这个系列文章.这一系列的文章中, 对 ...

  3. [.net 面向对象程序设计深入](6).NET MVC 6 —— 模型、视图、控制器、路由等的基本操作

    [.net 面向对象程序设计深入](6).NET MVC 6 —— 模型.视图.控制器.路由等的基本操作 1. 使用Visual Studio 2015创建Web App (1)文件>新建> ...

  4. [.net 面向对象程序设计深入](5)MVC 6 —— 构建跨平台.NET开发环境(Windows/Mac OS X/Linux)

    [.net 面向对象程序设计深入](5)MVC 6 —— 构建跨平台.NET开发环境(Windows/Mac OS X/Linux) 1.关于跨平台 上篇中介绍了MVC的发展历程,说到ASP.NET ...

  5. [.net 面向对象程序设计深入](4)MVC 6 —— 谈谈MVC的版本变迁及新版本6.0发展方向

    [.net 面向对象程序设计深入](4)MVC 6 ——谈谈MVC的版本变迁及新版本6.0发展方向 1.关于MVC 在本篇中不再详细介绍MVC的基础概念,这些东西百度要比我写的全面多了,MVC从1.0 ...

  6. [.net 面向对象程序设计深入](3)UML——在Visual Studio 2013/2015中设计UML活动图

    [.net 面向对象程序设计深入](3)UML——在Visual Studio 2013/2015中设计UML活动图 1.活动图简介 定义:是阐明了业务用例实现的工作流程. 业务工作流程说明了业务为向 ...

  7. [.net 面向对象程序设计深入](2)UML——在Visual Studio 2013/2015中设计UML用例图

    [.net 面向对象程序设计深入](2)UML——在Visual Studio 2013/2015中设计UML用例图  1.用例图简介 定义:用例图主要用来描述“用户.需求.系统功能单元”之间的关系. ...

  8. [.net 面向对象程序设计深入](1)UML——在Visual Studio 2013/2015中设计UML类图

    [.net 面向对象程序设计深入](1)UML——在Visual Studio 2013/2015中设计UML类图 1.UML简介 Unified Modeling Language (UML)又称统 ...

  9. [.net 面向对象程序设计进阶] (28) 结束语——告别2015

    [.net 面向对象程序设计进阶] (28) 结束语——告别2015 <.net面向对象程序设计进阶>这一系列文章写了太长的时间了,大概有半年没写,在年底又一口气写了好几篇.在整个过程中目 ...

随机推荐

  1. Js的substring和C#的Substring

    Js的substring 语法: 程序代码String.substring(start, end) 说明:返回一个从start开始到end(不包含end)的子字符串. 示例: 程序代码var str= ...

  2. Git-分支创建、拉取、切换

    git新建本地分支命令 1.创建本地分支 git branch 分支名,例如:git branch 2.0.1.20120806 注:2.0.1.20120806是分支名称,可以随便定义. 2.创建远 ...

  3. 【Tomcat】Tomcat集群session管理

    网上资料汇总: 关于 tomcat 集群中 session 共享的三种方法 Tomcat7集群共享Session 基于redis进行统一管理

  4. 使用 Node.js 搭建微服务网关

    目录 Node.js 是什么 安装 node.js Node.js 入门 Node.js 应用场景 npm 镜像 使用 Node.js 搭建微服务网关 什么是微服务架构 使用 Node.js 实现反向 ...

  5. nginx配置https转发到tomcat(使用自签名的证书)

    一.使用openSSL生成自签名的证书 1.生成RSA私钥 命令:openssl genrsa -des3 -out server.key 1024 说明:生成rsa私钥,des3算法,1024强度, ...

  6. 清空mysql数据表中的所有数据

    - 清空全部数据,不写日志,不可恢复,速度极快 truncate table_name;   -- 清空全部数据,写日志,数据可恢复,速度慢 delete from 表名     详情请查看区别

  7. 对象属性键值[key]属性问题

    1,obj[key]此时key代表是循环中的一个变量. var obj = {key:3,key1:1,key2:2,key3:3,toSting:4}; for (key in obj) { con ...

  8. layer弹出框确定前验证:弹出消息框(弹出两个layer)

    作者QQ:1095737364 QQ群:123300273 欢迎加入! layer 弹出框中经常遇到要弹出表单进行修改数据, 因此在弹出框中的表单需要验证数据, 就需要在弹出一个layer, 默认的设 ...

  9. 【读书笔记】iOS-网络-保护网络传输

    一,验证服务器通信. 二,HTTP认证. 手机银行应用有两种认证模式:标准验证与快速验证.标准验证只是提示用户输入用户名与密码,而快速验证则让用户注册设备,然后使用PIN进行验证,每次验证时无需用户名 ...

  10. 自定义多选框(checkbox)和单选框(radio)css样式

    直接上代码: input[type="radio"],input[type="checkbox"]{ -webkit-appearance: none; out ...