win10计算器_从0开始自制计算器!

先看看效果吧:

58b7b5784c497cad683d4d72ded3c0f9.png

943d6ad6a63d4f7220e2bdcc53db3eb7.gif

24ba206ad5b55c9e0a65a46e01137b3d.gif

7724b98ede9586c343481b920997294d.gif

很炫酷吧? 想不想要? ~~想要吧.~~ ~~当然作者知道你们肯定想.~~ ~~不然也不会点进来对不对.~~ 好.进入正题. @[TOC]

1.概述

这个是仿照win10自带的计算器制作的简化版本.是用Qt做的,直接把整个表达式输入然后得出计算结果. 主要分为三部分.界面部分,事件处理部分与表达式处理部分. - 界面部分就是看到的计算器,包括标题栏,中间的输出框,还有各个按键. - 事件处理就是处理对应的鼠标与键盘事件. - 表达式处理部分就是处理整个输入的字符串,返回计算的结果,当然这个还支持错误判断功能.

2.新建工程

选择Widgets Application.

e038fa8f5062d6443055cbbee93d1daf.png

起名字.

dbd03e9e76ea41dca96ad97c072a91ab.png

一般只需MinGW.

b5ebb63b7ad1620827e4315163cb0c02.png

这里默认即可,名字可以随便改

8a97067d1f51e6f70072b3d7c95eb9d5.png

b5b620596b3ad4b93e3cc52cbf59dc62.png

2.界面

(1) 按键

按键的话,基本上按着改就可以了.改布局,改颜色,改字体,主要就是这三个. 首先先打开.ui文件:

18a34d069fcd48781052971d458632a1.png

a.添加一个Grid Layout,调整好大小.

739a070b250ee8538ffe0e6c1747afb1.png

b.拖入Push Button作为按键,sizePolicy属性那里水平和垂直属性都选择Expanding.

47448362cfb4a1c7639596781a11125c.png

c.调整好颜色,设置styleSheet与字体

edf2064e2b493084e9ddb9b96a181a2d.png

这里给出作者的参考style:

border

字体:

93a7827b108828dcb778231c0cb30a3b.png

这里按个人喜好调整即可.

d.复制制作好的button,布好局

22104dbf8327aaccf29ce4d621905ea8.png

e.改内容

这里不仅把里面的字符改变,还要把相应的对象名也改变.

42fa8ca84c1773d1fdcda4b0557eaee0.png

78d8ad67aea50b3e094f911b0aee2eb3.png

再细调每一个按键,包括大小,字体与颜色,使总体效果更好.

f81838bcff32b61b8152c35c731581e1.png

数字要注意有"加粗"效果,符号的话尽量"精细"一点.

f.整体修改大小,同时加上间隔

f12f06c0db86a6a8c11219576e736401.png

调整好间隔.注意细节. 下面是win10自带的计算器:

7320ecac7a0450b534ce5cba367a65b3.png

看到间隔了没? 作者要的就是这种效果. 可以先运行看看.

e4afd73880359a7396df12046aed2d0f.png

两边的间隔的话一会配合widget的大小调整即可.

(2) 输出框

输出框很简单,就是一个QLineEdit.

a.添加QLineEdit

5c4f82631c1313e6964e04b2449ec40c.png

b.调整好大小,设置好背景颜色

1faa6b29ed4ed2ddc9d5182d0506ed8a.png

作者的qss:

border

c.设置字体,只读,对齐

0a9de5ad18969e931cba1807eb17e2db.png

530585c1e6c5520f44dd00ff0e909f1a.png

c710d73d61a0570ddf9eb5db4e7e5a3d.png

(3) 标题栏

标题栏其实也很简单,一个QBoxLayout

a.新建Horizontal Layout

1b4afacb8a088e4422ac0545968e727a.png

b.添加细节

93db22caa1d5c5e2363179fff970e166.png

QLabel输入标题,两个QPushButton表示最小化与关闭,同时加入两个Spacer,让标题与左边空出一些距离. 其实就是模仿win10的标题栏的效果

f27845d849ecd044f0a9e74151dad719.png

这里就不做最大化了.因为涉及到按钮的重新排布问题,这个可以自己选择实现.

(4)整体处理

a.标题栏

把上一步做的标题栏移到合适的位置,同时删除自带的QMenuBar,QToolBar,QStatusBar.

abf25a93b781f48d4496ab6aeb85023d.png

b.调整整体大小,同时添加透明度

2697105c6d3fda2af29d5a1a5f7e83cf.png

调整好后大概就那样,透明度这里选择了0.9.

~~真是完美啊!~~

3.事件处理

(1)光标事件

A.标题栏

a.拖动效果

首先把本来那个标题栏去掉.

38ccca68b88510c921f6434eec51f4f7.png
setWindowFlags

再在protected中加入鼠标监听函数:

f29206f75b85e834396280ddeea4a669.png
void 

私有成员中加入两个QPoint.分别表示当前窗口坐标与光标的坐标.

1792ffd0620e808030498e4ccc9b05e2.png
QPoint 

1f263ba031f5397d5d0be6cdb69eeaa6.png

第一个函数是鼠标按下时触发的,根据event->button()判断是否是左键,是的话获取mouse坐标,在设置window坐标. 当触发第二个函数时,即先判断是否按住左键不放,使用MainWindow的move方法移动窗口. event->globalPos()获取坐标后减去原来光标的坐标得到window坐标的变化量,再用原坐标加上这个变化量.

void 

b.最小化与关闭

这里以最小化为例,关闭也一样的,改一下函数调用即可. 在最小化按钮中右键选择Go to slot:

d099565b3f834cb5c7fe1103104bd2ee.png

选择clicked()

7335fb6bad8214bfb143e1c350bc7571.png

添加一个最小化函数:

6ccd5e0c3420fb62eb0a82c7fb29cad3.png

下面是关闭的函数:

3656ecb220fa00ccee01ee560a02fd95.png

B.按键

按键的鼠标事件包括两个: - 光标移入与移出事件,为按键添加阴影,加深颜色等 - 单击事件,在输出框中增减对应的字符

a.移入与移出事件

这里的实现方式是通过事件过滤器实现的.增加一个eventFilter()函数

de268030cfb102f38411a45cc152382c.png
bool 

3ae654d26376d3d162d27abf2701e5cf.png

首先通过event->type()判断事件类型,如果是光标悬停,再判断对应的各个对象增加阴影效果. addNumButtonEffet():

void 

这里QGraphicsDropShadowEffect *shadow事先初始化好了.

6e4161a99f2747cb17e7a3b96c085b19.png

11fadf7d24c26dcc6f6b66f5a61fbe3b.png

然后在添加事件过滤器:

a3d2b36333b4231de0a0dda94ff82b2b.png

这里可以对比一下有没有阴影的效果:

没有阴影:

43ae0bcc3804aa9550266a26e00c5494.gif

加上阴影:

cae97b89d21603ec9d0e16bd80ad39db.gif

呃....这里可能是截图工具的问题,看不来多大的效果,但是直接在机器上看是有比较大的区别的,建议还是加上阴影.

b.单击事件

单击事件就是单击了某个按键然后用户可以在输出框中看到对应的反应.

依次选择按键,右键Go to slot:

896daefcc5bff34d8acd40d3f92bd1e3.png

选择clicked()

4db4a76bd5a4246dedb85961c1ae6328.png

然后添加处理函数,作者这里自己实现了一个添加文本与清除焦点的函数,添加文本就是对应按键被光标单击后添加到输出框,至于为什么要清除焦点.... 因为... 因为空格. ~~因为作者的"良好"习惯,习惯在运算符前后加上空格~~ 单击后会把焦点保留在这个按钮上,键盘上敲空格默认会帮你"按一次"这个按钮,因此如果不清除焦点的话,在光标单击了某个按钮,比如7,按空格就会在输出框上输出7,光标单击了8后,按空格就会在输出框上输出8.

1464b948b443bcc5fa80ad2fc52c0169.png

0e92fc13e798a7aa40fe9aa000bee967.png

这里添加文本时还要注意默认的起提示作用的0.

void 

(2)键盘事件

键盘事件就是主要处理各个按键按下时的阴影与输出框添加输出. 键盘事件通过以下两个函数处理:

c5b8485eabb8aefbdb539c01e39b7dc7.png
void 

第一个是按键按下时触发的,第二个是松开按键触发的.

A.添加阴影

在按键按下时添加上阴影与颜色加深效果.

fa0cfedd4acceb30e7fab6c04a13af2c.png

通过event->key()依次判断各个键. 键位可以看这里

然后添加在keyRealeseEvent()中把对应的阴影去掉:

void 

这里之所以没有一个个按键去判断是因为有可能同时多个按键按下,然后同时松开后发现某个按键还存在阴影,因此统一当其中一个按键释放时去除所有按键的阴影.

B.添加输出

在输出框中添加输出,调用一个函数即可:

f61408591cf642704d1dbe7ec30f431d.png

4.整体细节再处理

(1)淡入效果

看看效果:

1e66b23873e243f0be7fc40f9225987e.gif

这里实际使用了Qt的动画,针对透明度改变的动画.

3b59f240edfe7871036dff092c864fb8.png
void 

第一行表示改变的是透明度,第二三行设置起始值与结束值,接下来设置动画时间(单位ms),然后开始动画.

(2)设置固定尺寸

这里可以不设置最大尺寸,但一定要设置最小尺寸.

372fa3a774a82494e3e1df8406049a96.png

设置这个实际上禁止了拖拽去改变大小.

(3)淡出效果

淡出效果与淡入效果类似. 不同的时需要添加计时处理,不能直接在exit(0)前调用fadeOut()函数,因为动画会在另一个线程启动,所以需要在主线程休眠指定秒数,等待淡出效果完成后,主线程再调用exit(0);

21e129ce5cc1d83279be5e36280d68e6.png
void 

其中addMSecs()表示要延迟的秒数,while循环体中表示处理本线程的事件,其中100表示处理事件最多100ms就返回本语句.

63f045fe54990e9042448181184f4827.png

这里就不放淡出效果的图片了.

5.表达式处理

由于这是整个字符串作为表达式进行输入,需要先进行判断再计算.所以分为判断与计算两部分. 这里使用了一个新开的控制台工程,后面会把这个整合起来.

(1)判断

使用了一个check类判断,由于只有10个数字按键,加减乘除,小数点,求余,求次幂,大中小括号,空格,所以可以分成这几类进行判断.

a.去除所有空格

void 

首先把所有空格去除,避免之后的判断.

b.分类判断

把表达式中的所有字符分成5类: - 数字 - 小数点 - 运算符号 + - * / ^ % - 左括号类 ( [ { - 右括号类 ) ] }

然后就是针对每个类型判断它的下一个字符是否是允许的类型,不是的话返回false. 比如碰上了一个 ( 或 [ 或 { 则它的下一个不能是运算符号或者小数点,当然允许-与+,因为有 (-7) (+234) 这种情况. 然后把这个符号保存下来判断后面是否是对应的右括号.

if

整个判断函数如下:

bool 

特别要注意下的就是碰到右括号的情况,除了要判断是否是单独存在的右括号,还有判断是否与前一个左括号匹配.

c.加0

这是针对单目运算符-的情况,比如(-7),然后把它转化为(0-7):

string 

在左小括号后判断是否是-或+,是的话对应位置插入0.

(2)计算

a.calc辅助类

calc辅助类中使用了两个栈,运算符栈与操作数栈.

private

其中有两个重要的方法:

bool 

第一个方法将下一个准备进入的符号作为参数,判断是否可以计算操作数栈的前两个数,如果可以的话,使用第二个函数进行计算. calculate()会将出栈两个操作数与一个运算符,得出结果后在将其压回操作数栈.

void 

下面是calc类:

class 

private封装了一些简单的对两个栈进行操作的工具方法,公有的pop()与get()是对运算符栈进行的操作.因为外部不需要对操作数栈进行操作,由calculate()进行操作,公有的push重载了,可以push到操作数栈或运算符栈.

b.计算部分

计算部分在这里直接放在了main中:

int 

对表达式的每个字符逐个处理,若是数字,提取出来并压栈. 若是右括号类,不断从运算符栈中提取直到把这段括号内的表达式计算完成. 否则若是左括号或者是运算符,当可以计算的时候一直计算,提取两个操作数运算并压栈,再把新的运算符压栈. 最后使用result()获取结果.

c.测试

这里就显示几个很长的例子算了 ~~当然作者测试了很多的例子~~

6542217240480c489e2e038b7e30fe6e.png

768a8e37d86364e9acbdb7649a63f9b8.png

e998b52418a102994e1b29fdab3184ac.png
6.6/{2.3+34.3*2.22-5%2+22%4*[2+3.4/5-(4.3+3.2*33.3)]+34.3} + 7.8*{2.4-6/6+0-0*[23.4-3.4/6+4*(2.2+3)]}+0 - 0 + 0.0 
= 10.8569

3.4 - (+3.34) + 34.3 * (-2) / 3.34 + {[(-3.4)^2/3.4+3.4/3]-3.32+[3*(-3)]}
= -28.2656

9^5-34.4^2.3+5%6-34+66%78-78%4 + (-3)*3.4 / {3*(-7)+[3*(-8)+3*(3.4+4.34)/9.3-3.2 + 0.0 - 0]+0.0 - 0}+3.4^4/6.888 
= 55683.2

~~不信的话可以手工计算一下.~~

6.整合

这部分把界面部分与表达式处理部分整合起来.

(1)设置界面的调用进程,并获取输出结果

计算表达式的程序叫MyCalc.exe,注意把它放在对应的工程文件夹下面,然后使用QProcess调用.

1a8748fe2cb4746c9bed0564ee7656c6.png

使用execute执行,表达式先去除所有的空格,然后作为命令行参数传递给计算程序,然后计算程序把计算结果写入到result.txt文件,Qt读取这个文件,如果读到#表示表达式输入错误,否则,则是正确的计算结果. 对于结果因为在计算程序中设置了fixed格式,因此对于 1+2 也会返回 3.000000 这步把多余的0去掉,还要注意小数点的情况.

(2)修改一些细节地方

a.鼠标键盘修改事件

ebc01c50552f006b85e5191026714ba4.png

8809415fcb4479ba4135a4e4b27cf6b0.png

修改setText的内容,把结果传递过去.

b.exe中设置数字的格式

41852e87611a3c1bcf711e56da5e4004.png

设置fixed格式,否则的话显示的是科学计数法,对小数位数有要求的话可以设置setprecision.

c.设置错误提示

这里出现错误时,输出"#",然后主程序读取到就会提示"表达式错误,请重新输入."

4993190f392bcc7fb974836bcc9f022b.png

还有除数为0的错误提示,这个要注意一下:

5c3e8dec1c7cb6ff5a782286afb6ac84.png

a2f933d7550c51818ed877aba65e0bc7.png

d.可以考虑把错误处理整合过来

比如输入了一个点,不能继续输入点,输入了一个乘号或者除号不能再继续输入另一个符号:

1d3a0bd910e75677a0b148a76c1a3ee1.gif

7.打包发布

(1) 首先去下载Enigma Virtual Box

(2) 添加环境变量

d65c5c685b920d3747dfa0fdcada83ee.png

把Qt文件夹下的如图所示的bin添加到Path环境变量,

(3) 打包库文件

使用windeployqt打包,首先把程序调成release模式,运行一次,生成release的exe,然后把exe复制到一个单独的文件夹,再用命令行进入到这个文件夹,运行

windelpoyqt xxx.exe

3377cb2bc01884e58bf1b1687fbed9f5.png

4c8abb1c592fc561895fe7c018664b94.png

这个命令把需要的dll复制到当前所在文件夹.

(4) 生成单个exe

打开Enigma Virtual Box,选择

d31a80e26de4241cecf45c56689fda65.png

842d9fc061b60e55e77a8100ef27c05f.png

第一个选择release的exe,第二个选择打包之后的文件夹,然后选择添加文件,选择递归添加,添加上一步生成的所有文件(夹).

1377335ba79689242e4023d966305860.png

这里选择压缩文件. 然后选择压缩等待完成即可.

(5) 测试

点击运行.

4247dcb5708dffbc67678dbac09daede.png

大功告成!!

8.源码

(1)github(里面包含完整可执行的单个exe)

注:由于使用了lfs上传大文件,所以clone的时候请使用git lfs clone,不能直接git clone.(这里提醒一下新手不要直接点击绿色那个clone or download然后Download zip....)
(2)码云

9.参考链接

1.Qt淡入

2.Qt按键

3.Qt标题栏

4.事件过滤器

5.Qt鼠标事件

6.Qt延时处理

7.Qt文件读写

8.Qt打包成单文件

10.最后

这个简单的计算器有很大的改进空间,比如可以添加各种"数": 正弦函数,余弦函数,正切函数,反正弦函数,指数函数,对数函数,高阶导数,抽象函数,复合函数.~~心里没数~~ 等等.另外还可以改进矩形的按钮,可以改成圆角矩形或者椭圆形. 另外,对于阴影的处理可以添加淡入淡出效果. 最后就是磨砂.因为win10的是有磨砂效果的,这个作者还不会.... 最后再上几个图,看看效果(由于动图大小的限制只是简单的表达式...):

85aa30723d9a5d0a6004025fa73bec4b.gif

2ed13e696e2f95d2ba9e97070fe0dd65.gif

3425c0d77fe02f94d039a989b7b7d9d1.gif

44c4456fd0909f163b5c4f456e390497.gif

希望你们也有一个属于自己的计算器!

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
计算器Win10系统中显示“请从原始位置重新安装”时,可能是由以下原因引起的: 1. 计算器文件被损坏:计算器程序的文件可能已经损坏或丢失,导致无法正常启动。这种情况下,我们可以尝试重新安装计算器程序来修复问题。 2. 系统文件损坏:计算器程序依赖于系统文件的支持,如果相关的系统文件损坏或丢失,可能会导致计算器无法正常工作。此时,我们可以使用系统文件检查工具(如sfc /scannow)来修复系统文件,并解决计算器显示问题。 3. 第三方软件冲突:有时,其他安装在系统中的第三方软件可能与计算器产生冲突,导致计算器无法正常运行。我们可以尝试关闭或卸载最近安装的软件,然后重新启动计算器来排除冲突问题。 为解决问题,我们可以采取以下步骤重新安装计算器: 1. 点击开始菜单,选择“设置”(齿轮图标)。 2. 在设置界面中,点击“应用”选项。 3. 在“应用和功能”页面,找到并点击“计算器”应用。 4. 在计算器的应用详情页,点击“高级选项”。 5. 在“重置”部分,点击“重置”按钮。 6. 在弹出的确认对话框中,点击“进行重置”。 7. 等待计算器重置完成后,重新启动计算器,看是否能够正常使用。 如果上述步骤仍然无法解决问题,我们可以尝试通过 Microsoft Store 下载并安装计算器应用,或者在Microsoft官网上下载Windows 10计算器的最新安装程序进行安装。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值