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. MVC应用程序播放RealPlayer(rmvb)视频

    以前Insus.NET开发asp.net时,一直无法把Realplayer的rmvb格式的视频在aspx网页播放与显示.现在学习ASP.NET MVC了,再次尝试这个,望它能在MVC的应用程序运行. ...

  2. Redis-其他命令

    1.排序 SORT :  SORT  sourcekey [BY pattern] [LIMIT offset count] [GET  pattern [GET  pattern  ...]] [A ...

  3. 【转】.NET NPOI操作Excel常用函数

    最近因项目接触了NPOI,感觉还是蛮不错的,网络上的教程普遍版本较老,本篇记录所常用操作,采用NPOI 2.0版本. 推荐: NPOI官方网站 NPOI 1.2.4/1.2.5 官方教程 新建Exce ...

  4. Hibernate高效查询,只查询部分/指定字段

    公司使用 DetachedCriteria detachedCriteria = DetachedCriteria.forClass(PeBulletin.class); detachedCriter ...

  5. 【JVM】3、JVM问题查找

    1.查看tomcat进程号 两种方式都可以查看tomcat进程号 ps -ef | grep tomcat-web jps -lmvV |grep tomcat-web 结果如下:2556 2.查看进 ...

  6. Servlet基础知识点整理

    常用注解 官方文档:https://docs.oracle.com/javaee/7/api/toc.htm WebServlet @WebServlet用于定义一个Servlet,等价于下面的xml ...

  7. centos7: ifconfig出现command not found解决办法

    问题 说下我linux配置情况,不一样的可以选择借鉴我的办法. 在虚拟机中以最小化方式安装centos7,ifconfig命令无效,而且在sbin目录中没有ifconfig文件. 原因 这是因为cen ...

  8. java锁的简化

    java使用单独的锁对象的代码展示 private Lock bankLock = new ReentrantLock(); //因为sufficientFunds是锁创建的条件所以称其为条件对象也叫 ...

  9. 理解Java之IO流

    流是一种抽象概念,它代表了数据的无结构化传递.用来进行输入输出操作的流就称为IO流. 一.IO流结构 1.流的分类方式 按流向分: 从文件/网络/内存等(数据源)到程序是输入流:从程序到文件/网络/内 ...

  10. cakephp怎么默认显示index/index文件

    在配置好cakephp之后,我们输入网址后都一般默认显示index/index 文件,那么怎么设置呢? 1.D:\www\cakephp\app\Config\routes.php