c++计算器后续(5)
自娱自乐:
大概是重新开始玩qt,然后MFC和第四步附加的作业大概不会去玩了。以上。
QT相关:
阶段一:
原来作业里举了qt和mfc这两个做界面的东西,网上都说qt容易上手,学了mfc再来看qt简直真爱之类的,而且当初也没有装vs(dev c++确实也够用。。。),所以就当时就选了qt咯。教程什么的感觉不好找(向来就不大会找资料也是很渣。。。不过抛弃百度,用必应和谷歌之后倒是感觉好点),感觉不错的教程又好长,大概看不完。。。种种理由(明明大家都是一样的时间,差距大概就是在这吧),所以当初只是找了个qt计算器的模板,照着大概看得懂的打了一些,然而还是没做完。现在是想认真的看看教程,知其然还要知其所以然,实际上顶多是知道个大概的程度就满意了。最后这是感觉不错的两个教程:教程一、教程二(如果看得下去的话,内容确实很多很详细,大概还在更)。
决定从头开始玩qt,于是把qt和vs都卸了重装,发现qt原来好像装错版本了,然后vs还是试用期已过。。。原来装的qt用的是MSVC编译器,所以才又得装vs,其实直接装MinGW编译的就好,然后vs登陆了半天大概是能用了(虽然我还不会用。。。)。接下来就开始看教程,虽然很多感觉计算器界面用不到,但是也能长长见识,毕竟是白得不能再白的小白。然而终究还是看不下去,看不多久就开始困,几天下来也没看多少,所以大概是带着看进去的一点东西先来完成一部分的界面。
这个阶段的界面只支持按钮输入,还没有关联键盘的输入,批量运算也还没实现,只能做到一些简单的计算器该有的东西,大概就是按按钮输入,按等号计算输出,下次计算自动清空。目前界面大概长这样:
然后来写写一些我想写的东西。一是刚开始在qt creator创建新项目的时候,它会有五个文件,然后里面的初始代码就看不懂,这个在教程里面也都有讲到,不然还有这个链接。我想说的是界面文件里面的那个有命名空间ui的类和那个文件里面的不是同一个东西,只是名字一样而已,然后想改类名的话还是在添加界面文件时就要取好了(大概是终于知道怎么改类名)。会添加文件之后,把原来的三个类的.cpp和.h文件包含进来就好了,能出结果这步问题不大,(不过后来为了实现信号和槽之类的功能,还是改成了继承与QObject的类),这一步主要的问题是算式有误的报错问题。下面是主要的代码:
Calculator.cpp
#include "scaner.h"
#include "printer.h"
#include "calculation.h"
#include "calculator.h"
#include "ui_calculator.h"
#include <queue>
#include <QDebug>
#include <string>
#include <iostream>
#include <QMessageBox>
using namespace std;
Calculator::Calculator(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Calculator)
{
ui->setupUi(this);
}
Calculator::~Calculator()
{
delete ui;
}
bool flag = 0; //是否清空输入框
string s_input; //用于计算的表达式
bool error_flag = 1; //算式是否无误
void Calculator::wrongInput(QString str)
{
error_flag = 0;
QMessageBox::warning(this, tr("ERROR"), str);
ui->lineEdit->clear();
s_input.clear();
}
void Calculator::on_pushButton_pointer_clicked()
{
if(flag)
{
ui->lineEdit->clear();
flag = 0;
}
s_input = s_input + ".";
ui->lineEdit->setText(ui->lineEdit->text() + QObject::tr("."));
}
...
void Calculator::on_pushButton_backspace_clicked()
{
ui->lineEdit->backspace();
if(!s_input.empty())
{
s_input.pop_back();
}
}
void Calculator::on_pushButton_escape_clicked()
{
ui->lineEdit->clear();
s_input.clear();
}
Scaner CScan;
Printer CPrint;
Calculation CCalculate;
double ans;
QString output;
queue<string> qs;
void Calculator::on_pushButton_equal_clicked()
{
QObject::connect(&CScan, SIGNAL(sendError(QString)), this, SLOT(wrongInput(QString)));
QObject::connect(&CCalculate, SIGNAL(sendError(QString)), this, SLOT(wrongInput(QString)));
error_flag = 1;
if(flag)
{
ui->lineEdit->clear();
}
s_input = s_input + "=";
ui->lineEdit->setText(ui->lineEdit->text() + QObject::tr("="));
qs = CScan.ToStringQueue(s_input);
ans = CCalculate.CalculateStringQueue(qs, error_flag);
if(error_flag)
{
ui->lineEdit->setText(output.setNum(ans, 'g', 10));
s_input.clear();
}
flag = 1;
}
main函数里就只有show一下Calculator这个类的一个对象而已,计算都在Calculator里实现,具体就是和等号按钮相关的那个槽函数,然后这次直接由按钮转到槽,没有那么多的connect。计算什么的都是上次的修修补补,主要这次是多了个报错的弹窗。在Scaner和Calculation这两个类里都有发报错信号的函数,在Calculator类里面有个对应的报错的槽函数,connect写在哪里也是想了挺久,最后大概就是找了个不会报错的地方,然后测试的时候果然还是有迷之bug。不过qt creator的debug比dev c++的正常多了,调试的很顺利,代码逐渐完善成上面那样。最后还有一个迷之bug是,多次输入错误算式的话,它会重复报错好多次。举个例子来说,你输入一个等号,它报错,关掉弹窗再输一个等号,它再报错,这时你关掉弹窗它还会再报错一次,然后你还要关一次弹窗才能输入,依次递增。。。最后是试着在把等号的槽函数末尾加了两句取消关联,也就是那两个connect写成disconnect,然后就可以了耶,不是很懂为什么,反正可以正常报错了哈。然后还有一件事是报错之后,正常的算式它也报错。。。不过还好这次bug没有找很久,qt creator的调试还是很好用的,用cout也有地方可以看输出。下面是报错的效果(还有一个是数字的位数超过十位的报错),点ok之后会清空让你再次输入,第一阶段大概就是这样了:
阶段二:
这步是实现从键盘获取输入,感觉不会很难(没想到这也算一步),搜索一下大概很快就能解决,但还是意外地做得生无所恋。。。我试了一下,光标在输入框里的时候,它本来就能获取输入,大概是要重载一下输入的函数吧。搜索看了一些例子之后,大概觉得是要重载
void QWidget::keyPressEvent(QKeyEvent *)
这个函数,会响应不同按键,里面至少要包括界面那20个按键,大致是这样:
void Calculator::keyPressEvent(QKeyEvent *e)
{
switch (e->key())
{
case Qt::Key_0:
Calculator::on_pushButton_0_clicked();
break;
...
}
}
然而事实是我用键盘输入的时候,它只会对回车键进行响应,其他的数字什么有显示在输入框里,但是根本就不是我重载的那个函数干的,因为我在重载函数里设了一堆断点,调试的时候都是按完回车直接跳到回车键那个情况的断点,所以实际上后台计算的式子就只有一个等号,于是欣慰的正常报错。。。大概是刚改完迷之重复报错的bug,它就又来一个迷之输入的bug,于是就开始找原因找得怀疑人生,感觉老是碰到莫名其妙的问题,也是很无奈。大概是找资料找不到相似的问题,我就跑去看了其他用qt做的同学的,发现他们也是重载这个函数啊,简直无法理解。找不同找到郁闷,也没发现啥不一样啊,于是找bug找到怀疑人生的时候,就开始乱改试运气了。。。我把重载的函数换成一个系列的
keyRelaeseEvent
(大概是放开键盘按钮的时候响应),还是在输入框显示光标的时候从键盘输入,然后这次它正常响应了耶。但是啊,并没有什么用,原来那个不重载也能输入的还在,所以真实情况是按1会显示一个1,放开又会输入一个1进去。。。所以原来那个到底是为什么重载失败了啊。我又改回keyPressEvent
,继续试来试去,偶然发现输入框没光标的时候它也可以输入耶,而且重载的函数居然正常调用,然后想起来其他同学的显示框用的部件好像是标签啊,唔,所以是因为这个不同吗。。。大概是因为我用的是单行(所以会响应回车)文本输入的部件,大概本来就有函数可以让它从键盘输入,所以重载的函数错掉了吧。我试了下,它还可以输入字母啥的,不过第四次要求只接收界面上的那几个,硬用这个好像很麻烦啊,那我还是用标签好了。唔,大概是知道vs code可以更改所有的匹配项,换掉所有的lineEdit还是挺快的。大概这就是第二阶段了,最后附上目前的界面效果(也就是给没颜色的标签上个色):阶段三:
最后的阶段就是实现从文件的输入输出了,实现过程虽然算不上一帆风顺,但也还好了其实。搜索不久就大概确定用
QFileDialog::getOpenFileName
这个函数,它弹出来的目录窗口就和我们的系统的一样。然后原来摸索过怎么改类名,大概知道现在要再添加一个qt的设计师界面类,点击按钮就实例一个对象show出来就好。然而我写完点了按钮之后,它会闪退的。。。想起教程解释初始的main函数的时候:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
大概.exec这个函数就可以让界面一直显示,不像我们原来的c++程序跑完就退出,可是不幸的是,我继承的QMainWindow没有这个函数。。。搜索的解决方法说将窗口设置为模态啊啥,试了下没有成功,于是又改成继承自QDialog类。QDialog类默认的窗口按钮有个问号,按了下并没有反应,可惜没有找到怎么实现的方法,只找到了怎么去掉的(链接)。下面是界面最终的样子:
大概是觉得确认按完有些直接退出有些不够友好,于是又加了个弹窗。唔,也就只会这些其实,实际上还是很不友好,大概勉强完成作业要求,不是很想玩了。最后又花了点时间规范一下代码,然后传到Github上当黑历史。。。以上。
c++计算器后续(5)的更多相关文章
- 使用HTML+CSS,jQuery编写的简易计算器后续(添加了键盘监听)
之前发布了一款简易的计算器,今天做了一下修改,添加了键盘监听事件,不用再用鼠标点点点啦 JS代码: var yunSuan = 0;// 运算符号,0-无运算;1-加法;2-减法;3-乘法;4-除法 ...
- c++计算器后续(4)
自娱自乐: 大概是终于做到没做完的部分了,第三步助教学长的评论还没去改,感觉那个把读取文件放到Scan里面比较麻烦,其他大概还好.以上. 文件读写: 先是原来的残留问题,都是和fstream :: o ...
- c++计算器后续(2)
自娱自乐: 大概是了解了一下前缀.中缀.后缀表示法是啥,并没有去深究,比如考虑实现啊,然后Calculation类里面的计算方法还是选用原来的直接对中缀表达式求值,只是把代码改得规范点,以上. 各表示 ...
- c++计算器后续(3)
自娱自乐: 本来只是想改改第二次的代码规范的,然后好像把原来的代码玩坏了,真是尴尬...然后大概是又发现了一些东西.以上. main的参数: 大概是说main函数的括号里是可以带参数的,写成这个样子: ...
- c++计算器后续(1)
自娱自乐: 大概是一直在说的代码规范,大概是玩一玩,以上. 代码规范: 参考原文:链接 相关节选: 4 程序的版式 4.4规则:较长的语句(>80字符)要分成多行书写. 4.5规则:不允许把多个 ...
- 微信小程序计算器后后续
改的眼睛都要瞎了,总算是知道问题出哪了 最后一段 在等号里面计算输入的数组,这个判断的主要操作是将输入的数据的数组进行数和符号的拆分然后再计算,把数按字符串输入数组,然后将数和符号进行拆分 ,最后通过 ...
- 微信小程序计算器模拟后续
今天按着自己的思路又重打了一遍 wxml没什么说的,就是分块起名,显示数字和结果的作为屏幕,数字键盘一行四块 <view class="onTop"> <view ...
- 【IOS开发笔记03-视图相关】简单计算器的实现
UIView 经过前几天的快速学习,我们初步了解的IOS开发的一些知识,中间因为拉的太急,忽略了很多基础知识点,这些知识点单独拿出来学习太过枯燥,我们在今后的项目中再逐步补齐,今天我们来学习APP视图 ...
- Js函数初学者练习(一)switch-case结构实现计算器。
前 言 JRedu 给大家介绍一点JS函数的练习题希望初学者多做一些练习能够更好的掌握JS的函数,以及能够提升大家的逻辑思维.(我也是个渣渣希望路过的大神多提建议或意见) 希望能够对大家有所帮助 ...
随机推荐
- sql中字符串连接
有时候我们需要将由不同栏位获得的资料串连在一起,每一种数据库都提供一定的方法来达到这个目的,比如: MySQL: CONCAT() Oracle: CONCAT(), || SQL Server: + ...
- R语言 删除变量rm函数
变量可以通过使用 rm()函数来删除.下面我们删除变量var.3.然后再打印变量时出现异常错误. rm(var.3) print(var.3) 当上面的代码执行时,它产生以下结果: [1] " ...
- 通过开机广播(broadcast)通知应用
1. 概念 开机的时候,系统会发送一则广播,所有有标记的应用(通过广播接收者)都会获取得到,然后可以通过广播接收者去处理一些事情,比如启动该应用,或者处理数据: 代码:https://github.c ...
- 移动端的touchstart,touchmove,touchend事件中的获取当前touch位置
前提:touchstart,touchmove,touchend这三个事件可以通过原生和jq绑定. 原生:document.querySelector("#aa").addEven ...
- 获取访问MySQL的应用
接到业务需求,要我统计哪个应用访问了哪些表,一般来讲可以通过: 1.show full processlist; 2.SELECT HOST FROM information_schema.proce ...
- Knockout.js Attr绑定
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8&quo ...
- 如鹏网学习笔记(十三)EasyUI
一.EasyUI简介 是一组基于JQuery的UI插件集合 主要作用:为JQuery对象提供新的方法,实现新的功能 可以快速创建出简洁.友好.美观的页面,非常适合做网站后台管理页面(不够漂亮,不适合做 ...
- 引入第三方js文件,报错
错误:Mixed Content: The page at 'https://localhost:44336/MENU' was loaded over HTTPS, but requested an ...
- [javaSE] 网络编程(URL)
获取URL对象,new出来,构造参数:String的路径 调用URL对象的getProtocal()方法,获取协议 调用URL对象的getHost()方法,获取主机 调用URL对象的getPath() ...
- springboot手动配置数据源:
@Configuration @EnableTransactionManagement @PropertySource(value = {"classpath:config/source.p ...