用python编写一个简单的计算器

基本功能

一个简单的计算器需要一个简单操作界面、会运算加减乘除运算的基本功能、支持键盘快捷键入

创建简单的操作界面

操作界面用pygame完全可行
主程序如下:

import pygame
import sys
from settings import Settings
import functions as fu
from pygame.sprite import Group
from classs import *
from digital import *

def calculator():
    pygame.init()
    setting=Settings()
    #创建设置参数
    screen=pygame.display.set_mode((setting.screen_width,setting.screen_height))
    pygame.display.set_caption('计算器')
    #创建pygame主屏幕
    calculator_screen=Calculator_screen(screen,setting)
    #创建计算器屏幕,用于显示数字
    buttons=Group()
    #创建数字按钮编组
    gnbuttons=Group()
    #创建特殊按钮编组,比如+,-,×....
    daorus=Group()
    #创建用户自定义功能按钮
    button_lei=fu.digital_button(screen,setting,buttons)
    #将所有数字按钮存储在一个列表中
    gn_button_lei=fu.gn_button(screen,setting,gnbuttons)
    #将所有特殊按钮存储在一个列表中
    daoru_lei=fu.daoru_button(screen,setting,daorus)
    #将用户自定义功能按钮存储在一个列表中
    digital=Digital_jihe()
    #创建用于显示的数字
    shu=Shu(screen,setting,calculator_screen,digital)
    #创建用于在计算器屏幕上显示的数字
    tips=Tips(calculator_screen,setting,screen,shu)
    #创建提示标记,显示必要时要提醒的信息
    while True:
        """开始屏幕主循环"""
        screen.fill(setting.bg_color)
        #用颜色填充屏幕
        fu.check_events(button_lei,gn_button_lei,calculator_screen,
        digital,shu,setting,tips,daoru_lei)
        #检测鼠标与键盘响应事件
        fu.update_screen(calculator_screen,buttons,
        gnbuttons,screen,shu,tips,daorus)
        #持续更新屏幕内容
calculator()

实际运行效果:
计算器界面效果
数字键和加减乘除等功能键是分开的,底部按钮用于导入导出计算器的参数设置为txt文件,方便使用者自行修改部分设置。

键盘快捷键

加减乘除:→/←/↑/↓
等号:enter
后退:backspace
清除:空格
次方符号:左shift
导入:F1
导出:F2
负号:,
小数点:.
数字:数字键+小键盘数字键

鼠标和键盘操作部分:

def check_events(button_lei,gn_button_lei,calculator_screen,
digital,shu,setting,tips,daoru_lei):
    """检测鼠标和键盘事件"""
    x=check_edges(calculator_screen,digital,shu)
    y=check_dier_edges(calculator_screen,digital,shu)
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            sys.exit(0)
        if event.type==pygame.KEYDOWN:
            keydown(event,button_lei,gn_button_lei,setting,
            digital,shu,calculator_screen,x,y,tips,daoru_lei)
        if event.type==pygame.KEYUP:
            keyup(event,button_lei,gn_button_lei,setting,daoru_lei)
        if event.type==pygame.MOUSEBUTTONDOWN:
            mouse_x,mouse_y=pygame.mouse.get_pos()
            mousedown(event,mouse_x,mouse_y,button_lei,gn_button_lei,
            calculator_screen,digital,shu,setting,x,y,tips,daoru_lei)
        if event.type==pygame.MOUSEBUTTONUP:
            mouse_x,mouse_y=pygame.mouse.get_pos()
            mouseup(event,mouse_x,mouse_y,button_lei,gn_button_lei,setting,daoru_lei)
def keydown(event,button_lei,gn_button_lei,setting,
digital,shu,calculator_screen,x,y,tips,daoru_lei):
    """响应键盘按下事件"""
    if event.key==pygame.K_ESCAPE:
        sys.exit(0)
    elif event.key==pygame.K_9 or event.key==pygame.K_KP9:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,9)
    elif event.key==pygame.K_8 or event.key==pygame.K_KP8:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,8)
    elif event.key==pygame.K_7 or event.key==pygame.K_KP7:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,7)
    elif event.key==pygame.K_6 or event.key==pygame.K_KP6:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,6)
    elif event.key==pygame.K_5 or event.key==pygame.K_KP5:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,5)
    elif event.key==pygame.K_4 or event.key==pygame.K_KP4:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,4)
    elif event.key==pygame.K_3 or event.key==pygame.K_KP3:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,3)
    elif event.key==pygame.K_2 or event.key==pygame.K_KP2:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,2)
    elif event.key==pygame.K_1 or event.key==pygame.K_KP1:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,1)
    elif event.key==pygame.K_0 or event.key==pygame.K_KP0:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,0)
    elif event.key==pygame.K_BACKSPACE:
        k.button_tui_click(calculator_screen,gn_button_lei,setting,digital,shu)
    elif event.key==pygame.K_KP_PLUS or event.key==pygame.K_RIGHT:
        k.gnbutton_click(gn_button_lei,setting,digital,shu,calculator_screen,'+')
    elif event.key==pygame.K_KP_MINUS or event.key==pygame.K_LEFT:
        k.gnbutton_click(gn_button_lei,setting,digital,shu,calculator_screen,'-')
    elif event.key==pygame.K_KP_MULTIPLY or event.key==pygame.K_UP:
        k.gnbutton_click(gn_button_lei,setting,digital,shu,calculator_screen,'×')
    elif event.key==pygame.K_KP_DIVIDE or event.key==pygame.K_DOWN:
        k.gnbutton_click(gn_button_lei,setting,digital,shu,calculator_screen,'÷')
    elif event.key==pygame.K_LSHIFT:
        k.gnbutton_click(gn_button_lei,setting,digital,shu,calculator_screen,'^')
    elif event.key==pygame.K_EQUALS:
        k.button_deng_click(gn_button_lei,setting,digital,shu,tips)
    elif event.key==pygame.K_RETURN:
        k.button_deng_click(gn_button_lei,setting,digital,shu,tips)
    elif event.key==pygame.K_KP_ENTER:
        k.button_deng_click(gn_button_lei,setting,digital,shu,tips)
    elif event.key==pygame.K_c:
        k.button_qing_click(gn_button_lei,setting,digital,shu,calculator_screen)
    elif event.key==pygame.K_SPACE:
        k.button_qing_click(gn_button_lei,setting,digital,shu,calculator_screen)
    elif event.key==pygame.K_COMMA:
        k.button_fu_click(button_lei,setting,digital,shu)
    elif event.key==pygame.K_PERIOD or event.key==pygame.K_KP_PERIOD:
        k.button_pot_click(button_lei,setting,digital,shu)
    elif event.key==pygame.K_F1:
        k.daoru_click(setting,daoru_lei)
    elif event.key==pygame.K_F2:
        k.daochu_click(setting,daoru_lei,tips,shu)

def keyup(event,button_lei,gn_button_lei,setting,daoru_lei):
    """响应键盘松开"""
    for x in button_lei:
        x.color=setting.button_color
    for x in gn_button_lei[:7]:
        x.color=setting.gnbutton_color
    for x in daoru_lei:
        x.color=setting.daoru_color
    gn_button_lei[7].color=setting.deng_color

def mouseup(event,mouse_x,mouse_y,button_lei,
gn_button_lei,setting,daoru_lei):
    """响应鼠标按钮松开"""
    for x in button_lei:
        x.color=setting.button_color
    for x in gn_button_lei[:7]:
        x.color=setting.gnbutton_color
    for x in daoru_lei:
        x.color=setting.daoru_color
    gn_button_lei[7].color=setting.deng_color

def mousedown(event,mouse_x,mouse_y,button_lei,gn_button_lei,
calculator_screen,digital,shu,setting,x,y,tips,daoru_lei):
    """响应鼠标按下"""
    button_9_click=button_lei[9].rect.collidepoint(mouse_x,mouse_y)
    button_8_click=button_lei[8].rect.collidepoint(mouse_x,mouse_y)
    button_7_click=button_lei[7].rect.collidepoint(mouse_x,mouse_y)
    button_6_click=button_lei[6].rect.collidepoint(mouse_x,mouse_y)
    button_5_click=button_lei[5].rect.collidepoint(mouse_x,mouse_y)
    button_4_click=button_lei[4].rect.collidepoint(mouse_x,mouse_y)
    button_3_click=button_lei[3].rect.collidepoint(mouse_x,mouse_y)
    button_2_click=button_lei[2].rect.collidepoint(mouse_x,mouse_y)
    button_1_click=button_lei[1].rect.collidepoint(mouse_x,mouse_y)
    button_0_click=button_lei[0].rect.collidepoint(mouse_x,mouse_y)
    button_fu_click=button_lei[10].rect.collidepoint(mouse_x,mouse_y)
    button_pot_click=button_lei[11].rect.collidepoint(mouse_x,mouse_y)
    button_tui_click=gn_button_lei[4].rect.collidepoint(mouse_x,mouse_y)
    button_jia_click=gn_button_lei[0].rect.collidepoint(mouse_x,mouse_y)
    button_jian_click=gn_button_lei[1].rect.collidepoint(mouse_x,mouse_y)
    button_cheng_click=gn_button_lei[2].rect.collidepoint(mouse_x,mouse_y)
    button_chu_click=gn_button_lei[3].rect.collidepoint(mouse_x,mouse_y)
    button_qing_click=gn_button_lei[5].rect.collidepoint(mouse_x,mouse_y)
    button_fang_click=gn_button_lei[6].rect.collidepoint(mouse_x,mouse_y)
    button_deng_click=gn_button_lei[7].rect.collidepoint(mouse_x,mouse_y)
    button_daochu_click=daoru_lei[1].rect.collidepoint(mouse_x,mouse_y)
    button_daoru_click=daoru_lei[0].rect.collidepoint(mouse_x,mouse_y)
    x=check_edges(calculator_screen,digital,shu)
    y=check_dier_edges(calculator_screen,digital,shu)
    #创建数字9的功能
    if button_9_click:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,9)
    #创建数字8的功能
    elif button_8_click:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,8)
    #创建数字7的功能
    elif button_7_click:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,7)
    #创建数字6的功能
    elif button_6_click:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,6)
    #创建数字5的功能
    elif button_5_click:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,5)
    #创建数字4的功能
    elif button_4_click:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,4)
    #创建数字3的功能
    elif button_3_click:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,3)
    #创建数字2的功能
    elif button_2_click:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,2)
    #创建数字1的功能
    elif button_1_click:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,1)
    #创建数字0的功能
    elif button_0_click:
        k.button_click(calculator_screen,button_lei,setting,digital,shu,x,y,0)
    #创建负号的功能
    elif button_fu_click:
        k.button_fu_click(button_lei,setting,digital,shu)
    #创建功能键退一格的功能
    elif button_tui_click:
        k.button_tui_click(calculator_screen,gn_button_lei,setting,digital,shu)
    #创建小数点的功能
    elif button_pot_click:
        k.button_pot_click(button_lei,setting,digital,shu)
    #创建按钮加号的功能
    elif button_jia_click:
        k.gnbutton_click(gn_button_lei,setting,digital,shu,calculator_screen,'+')
    #创建按钮减号的功能
    elif button_jian_click:
        k.gnbutton_click(gn_button_lei,setting,digital,shu,calculator_screen,'-')
    #创建按钮乘号功能
    elif button_cheng_click:
        k.gnbutton_click(gn_button_lei,setting,digital,shu,calculator_screen,'×')
    # 创建按钮除号功能
    elif button_chu_click:
        k.gnbutton_click(gn_button_lei,setting,digital,shu,calculator_screen,'÷')
    #创建功能按钮功能
    elif button_fang_click:
        k.gnbutton_click(gn_button_lei,setting,digital,shu,calculator_screen,'^')
    #创建一键清屏的功能
    elif button_qing_click:
        k.button_qing_click(gn_button_lei,setting,digital,shu,calculator_screen)
    #创建等号的功能
    elif button_deng_click:
        k.button_deng_click(gn_button_lei,setting,digital,shu,tips)
    elif button_daochu_click:
        k.daochu_click(setting,daoru_lei,tips,shu)
    elif button_daoru_click:
        k.daoru_click(setting,daoru_lei)

输入的数字不能超过屏幕部分

def check_edges(calculator_screen,digital,shu):
    """检查数字与计算器屏幕边缘"""
    if int(shu.diyi_image_rect.width)<calculator_screen.rect.width-30:
        return(1)
    else:
        return(0)

def check_dier_edges(calculator_screen,digital,shu):
    """检查第二排数字与计算器边缘"""
    if int(shu.dier_image_rect.width)<calculator_screen.rect.width-30:
        return(1)
    else:
        return(0)

创建数字按钮的类:

class Button(Sprite):
    """创建一个计算器按钮的类"""
    def __init__(self,screen,setting,msg):
        super().__init__()
        self.screen=screen
        self.screen_rect=self.screen.get_rect()
        self.color=setting.button_color
        self.width=setting.button_width
        self.height=setting.button_height
        self.text_color=setting.button_ziti_color
        self.font=pygame.font.SysFont('Calibri',setting.button_ziti_size)
        self.rect=pygame.Rect(0,0,self.width,self.height)
        
        self.prep_msg(msg)
        
    def prep_msg(self,msg):
        """将msg渲染为图像"""
        self.text_image=self.font.render(msg,True,self.text_color)
        self.text_image_rect=self.text_image.get_rect()
        self.text_image_rect.center=self.rect.center

    def draw_button(self):
        """在主屏幕上绘制按钮"""
        self.screen.fill(self.color,self.rect)
        self.screen.blit(self.text_image,self.text_image_rect)

创建数字按钮的实例:

def digital_button(screen,setting,buttons):
    """创建数字按钮并储存在编组中"""
    #创建数字按键
    button_9=Button(screen,setting,'9')
    button_8=Button(screen,setting,'8')
    button_7=Button(screen,setting,'7')
    button_6=Button(screen,setting,'6')
    button_5=Button(screen,setting,'5')
    button_4=Button(screen,setting,'4')
    button_3=Button(screen,setting,'3')
    button_2=Button(screen,setting,'2')
    button_1=Button(screen,setting,'1')
    button_0=Button(screen,setting,'0')
    button_fu=Button(screen,setting,'-')
    button_pot=Button(screen,setting,'.')
    button_lei=[button_0,button_1,button_2,button_3,
    button_4,button_5,button_6,button_7,button_8,button_9,button_fu,button_pot]
    gaodu=du(setting)

    #对按钮的位置进行排序
    button_9.rect.y=gaodu
    button_9.rect.x=15
    button_9.text_image_rect.center=button_9.rect.center
    button_8.rect.y=gaodu
    button_7.rect.y=gaodu
    button_8.rect.x=button_9.rect.x+setting.button_jianju+setting.button_width
    button_7.rect.x=button_8.rect.x+setting.button_jianju+setting.button_width
    button_6.rect.y=button_9.rect.y+setting.button_height+setting.button_jianju
    button_6.rect.x=button_9.rect.x
    button_5.rect.x=button_6.rect.x+setting.button_jianju+setting.button_width
    button_5.rect.y=button_6.rect.y
    button_4.rect.y=button_6.rect.y
    button_4.rect.x=button_5.rect.x+setting.button_width+setting.button_jianju
    button_3.rect.y=button_6.rect.y+setting.button_height+setting.button_jianju
    button_3.rect.x=button_6.rect.x
    button_2.rect.x=button_3.rect.x+setting.button_width+setting.button_jianju
    button_2.rect.y=button_3.rect.y
    button_1.rect.y=button_3.rect.y
    button_1.rect.x=button_2.rect.x+setting.button_jianju+setting.button_width
    button_0.rect.x=button_2.rect.x
    button_0.rect.y=button_2.rect.y+setting.button_height+setting.button_jianju
    button_pot.rect.x=button_0.rect.x+setting.button_jianju+setting.button_width
    button_pot.rect.y=button_0.rect.y
    button_fu.rect.x=button_3.rect.x
    button_fu.rect.y=button_0.rect.y
    for x in button_lei:
        #将按钮符号显示在按钮中央
        bottons.add(x)
        dange.text_image_rect.center=dange.rect.center
    return button_lei

加减乘除等特殊按钮都是这样的

屏幕和显示部分

计算器显示屏:

class Calculator_screen():
    """创建一个计算器屏幕的类"""
    def __init__(self,screen,setting):
        self.screen=screen
        self.screen_rect=self.screen.get_rect()
        self.width=setting.calculator_screen_width
        self.height=setting.calculator_screen_height
        self.color=setting.calculator_screen_color
        self.rect=pygame.Rect(0,0,self.width,self.height)
        self.rect.centerx=self.screen_rect.centerx
        self.rect.y=int((self.screen_rect.width-self.width)/2)

    def draw_calculator_screen(self):
        """在主屏幕上绘制计算器屏幕"""
        pygame.draw.rect(self.screen,self.color,self.rect)

计算器显示屏上的数字部分:

class Digital_jihe():
 """创建一个储存所有计算器屏幕数字的类"""
 def __init__(self):
     self.diyi=" "
     self.fuhao=" "
     self.dier=" "
     self.daan=" "
 def chushihua(self):
     """数字全部恢复原始状态"""
     self.diyi=' '
     self.fuhao=' '
     self.dier=' '
     self.daan=' '
class Shu(Sprite):
  """创建表示屏幕数字的类"""
  def __init__(self,screen,setting,calculator_screen,digital):
      super().__init__()
      self.screen=screen
      self.setting=setting
      self.digital=digital
      self.calculator_screen=calculator_screen
      self.warning="Divisor can't be zero"
      self.screen_rect=self.screen.get_rect()
      self.digital_color=setting.digital_color
      self.font=pygame.font.SysFont('Calibri',setting.digital_size)
      
      self.prep_diyi()
      self.prep_fuhao()
      self.prep_dier()
      self.prep_juxing()
      self.prep_daan()
      
  def prep_juxing(self):
      """在屏幕中插入矩形表示等号"""
      self.rect_height=3
      self.rect_width=self.calculator_screen.rect.width-10
      self.rect_color=self.setting.calculator_screen_color
      self.rect=pygame.Rect(0,0,self.rect_width,self.rect_height)
      self.rect.centerx=self.calculator_screen.rect.centerx
      self.rect.y=self.dier_image_rect.y+self.dier_image_rect.height+5
      self.rect_chufa=False
      

  def prep_diyi(self):
      """渲染第一数字为图像"""
      number_1=self.digital.diyi
      self.xin_str=fu.qianfenhao(number_1)
      if self.xin_str=='0':
          self.diyi_image=self.font.render(number_1,True,self.setting.digital_color)
      else:
          self.diyi_image=self.font.render(self.xin_str,True,self.setting.digital_color)
      self.diyi_image_rect=self.diyi_image.get_rect()
      self.diyi_image_rect.right=self.calculator_screen.rect.right-10
      self.diyi_image_rect.y=self.calculator_screen.rect.y+10
  
  def prep_fuhao(self):
      """渲染符号为图像"""
      fuhao=self.digital.fuhao
      self.fuhao_image=self.font.render(fuhao,True,self.setting.fuhao_color)
      self.fuhao_image_rect=self.fuhao_image.get_rect()
      self.fuhao_image_rect.left=self.calculator_screen.rect.left+10
      self.fuhao_image_rect.y=self.diyi_image_rect.y+self.diyi_image_rect.height
  
  def prep_dier(self):
      """渲染第二数字为图像"""
      number_2=self.digital.dier
      self.xin_str=fu.qianfenhao(number_2)
      if self.xin_str=='0':
          self.dier_image=self.font.render(number_2,True,self.setting.digital_color)
      else:
          self.dier_image=self.font.render(self.xin_str,True,self.setting.digital_color)
      self.dier_image_rect=self.dier_image.get_rect()
      self.dier_image_rect.right=self.calculator_screen.rect.right-10
      self.dier_image_rect.y=self.fuhao_image_rect.y

  def prep_daan(self):
      """渲染计算结果为图像"""
      self.result=self.digital.daan
      self.tips=False
      x=fu.qianfenhao(self.result)
      #在计算结果中插入逗号
      if self.result!='warning':
          self.result_image=self.font.render(x,True,self.setting.digital_color)
      else:
          self.result_image=self.font.render(self.warning,True,self.setting.warning_color)
      self.result_image_rect=self.result_image.get_rect()
      self.result_image_rect.right=self.calculator_screen.rect.right-10
      self.result_image_rect.y=self.rect.y+self.rect.height+5
      s=fu.check_daan_edges(self.calculator_screen,self.result_image_rect,x)
      if s==0:
          self.tips=True
      elif s==1:
          self.tips=False
  
  def draw_digital(self):
      """在屏幕上绘制数字"""
      self.screen.blit(self.diyi_image,self.diyi_image_rect)
      self.screen.blit(self.fuhao_image,self.fuhao_image_rect)
      self.screen.blit(self.dier_image,self.dier_image_rect)
      self.screen.blit(self.result_image,self.result_image_rect)
      pygame.draw.rect(self.screen,self.rect_color,self.rect)
class Tips():
 """创建提醒符号"""
 def __init__(self,calculator_screen,setting,screen,shu):
     self.setting=setting
     self.shu=shu
     self.screen=screen
     self.calculator_screen=calculator_screen
     self.font=pygame.font.SysFont('KaiTi',30)
     self.neirong='未显示全部结果!'
     self.rect=pygame.Rect(0,0,(self.setting.screen_width-self.setting.calculator_screen_width)/2,shu.diyi_image_rect.height)
     self.rect.x=self.calculator_screen.rect.right
     self.rect.y=self.shu.result_image_rect.y
     
 def draw_tips(self):
     """在屏幕上绘制提醒符号"""
     self.rect_color=self.setting.bg_color
     if self.shu.tips==False:
         self.color=self.setting.calculator_screen_color
     elif self.shu.tips==True:
         self.color=self.setting.tixing_chufa_color
     self.image=self.font.render(self.neirong,True,self.color)
     self.image_rect=self.image.get_rect()
     self.image_rect.centerx=self.calculator_screen.rect.centerx
     self.image_rect.bottom=self.calculator_screen.rect.bottom
     self.screen.blit(self.image,self.image_rect)
     pygame.draw.rect(self.screen,self.rect_color,self.rect)

实际显示效果:
在这里插入图片描述
在这里插入图片描述

数字按钮和功能键

def button_click(calculator_screen,
button_lei,setting,digital,shu,x,y,z):
    """创建数字按钮的响应功能"""
    button_lei[z].color=setting.button_chufa_color
    if shu.tips:
        shu.tips=False
    if digital.fuhao==' ' and x==1:
        digital.diyi+=str(z)
    elif digital.fuhao!=' ' and y==1:
        digital.dier+=str(z)
    if shu.rect_chufa:
        fu.calculator_screen_cler(calculator_screen,digital,shu,setting,1)
        digital.diyi=' '
        digital.diyi+=str(z)
    shu.prep_diyi()
    shu.prep_dier()

def gnbutton_click(gn_button_lei,setting,
digital,shu,calculator_screen,z):
    """创建符号按钮的响应功能"""
    if shu.tips:
        shu.tips=False
    if z=='+':
        y=0
    elif z=='-':
        y=1
    elif z=='×':
        y=2
    elif z=='÷':
        y=3
    elif z=='^':
        y=6
    gn_button_lei[y].color=setting.button_chufa_color
    if len(digital.diyi)>1 and not shu.rect_chufa:
        digital.fuhao=z
        shu.prep_fuhao()
    elif shu.rect_chufa:
        digital.diyi=fu.insertt(shu.result)
        digital.fuhao=z
        fu.calculator_screen_cler(calculator_screen,digital,shu,setting,2)

负号和小数点的输入

负号比较特殊,只能输入一次
小数点也只能输入一次

def button_fu_click(button_lei,setting,digital,shu):
    """创建负号的响应功能"""
    button_lei[10].color=setting.button_chufa_color
    #按钮按下改变颜色以后触发反馈
    if shu.tips:
        shu.tips=False
    if digital.fuhao==' ':
        number=digital.diyi
    elif digital.fuhao!=' ':
        number=digital.dier
    if len(number)>1:
    #如果数字的长度大于1,则无法输入负号
        None
    else:
        digital_list=list(number)
        digital_list.append('-')
        xin=''.join(digital_list)
    if digital.fuhao==' ':
        try:
            digital.diyi=xin
        except UnboundLocalError:
            pass
    elif digital.fuhao!=' ':
        try:
            digital.dier=xin
        except UnboundLocalError:
            pass
    shu.prep_diyi()
    shu.prep_dier()

小数点的输入需要考虑数据中有无负号

def button_pot_click(button_lei,setting,digital,shu):
    """创建小数点的响应功能"""
    if shu.tips:
        shu.tips=False
    button_lei[11].color=setting.button_chufa_color
    #按钮按下改变颜色以触发反馈
    if digital.fuhao==' ':
        digital_list=list(digital.diyi)
    elif digital.fuhao!=' ':
        digital_list=list(digital.dier)
    digital_lenth=len(digital_list)
    if "-" in digital_list:
    #如果负号包含在数据中
        if digital_lenth>=3:
            if '.' not in digital_list:
                digital_list.append('.')
    elif "-" not in digital_list:
    #如果负号不含在数据中
        if digital_lenth>=2:
            if '.' not in digital_list:
                digital_list.append('.')
    xin=''.join(digital_list)
    if digital.fuhao==' ':
        digital.diyi=xin
    elif digital.fuhao!=' ':
        digital.dier=xin
    shu.prep_diyi()
    shu.prep_dier()

在数据中插入逗号

将数据的字符串以小数点为界,拆分为整数部分和小数部分,再在整数部分插入逗号,如果第一个是负号则直接显示在屏幕上。如果直接插入的话,会在在输入的时候按小数点会没反应,按两次才会有小数点,拆开可以避免这种情况。如果第一个时负号时不直接显示,会导致屏幕上不会出现负号,按两次才会出现。

def qianfenhao(number):
    """在数据的整数部分插入逗号"""
    try:
        number=number.strip()
        if number=='-':
            xin_str='-'
        else:
            number_list=list(number)
            xuhao=0
            dclliebiao_1=[]
            dclliebiao_2=[]
            if '.' in number_list:
                for i,x in enumerate(number_list):
                    if x=='.':
                        xuhao=i
                for x in number_list[:xuhao]:
                    dclliebiao_1.append(x)
                for x in number_list[xuhao:]:
                    dclliebiao_2.append(x)
                xin=''.join(dclliebiao_1)
                xiaoshu=str(''.join(dclliebiao_2))
                try:
                    xin_int=int(xin)
                    xin_str=str("{:,}".format(xin_int))+xiaoshu
                except ValueError:
                    xin_str=' '        
            elif '.' not in number_list:
                try:
                    xin_int=int(number)
                    xin_str=str('{:,}'.format(xin_int))
                except ValueError:
                    xin_str=' '           
        return xin_str
    except AttributeError:
        pass

显示效果:
在这里插入图片描述

核心计算部分

这是独立的函数,进行加减乘除和次方计算,先把在屏幕上显示的字符串转换为纯数字再进行运算。需要将数字转换为浮点数才能计算出准确结果,但浮点数会在屏幕上多显示一个0,例如:12÷4=3.0,因此还需要一个函数将后面的0除去。

def jisuan(number_1,number_2,fuhao):
    """执行计算,并返回计算结果"""
    number_1=number_1.strip()
    number_2=number_2.strip()
    number_3=' '
    fuhao=fuhao
    x,y=conversion(number_1,number_2)
    if fuhao=='+':
        number_3=x+y
    elif fuhao=='-':
        number_3=x-y
    elif fuhao=='×':
        number_3=x*y
    elif fuhao=='÷':
        try:
            number_3=x/y
            number_3=chuling(number_3)
        except ZeroDivisionError:
            number_3='warning'
    elif fuhao=='^':
        number_3=chengfang(x,y)
        number_3=chuling(number_3)
    return number_3

def conversion(number_1,number_2):
    """将字符转化为纯数字"""
    number_1_list=list(number_1)
    number_2_list=list(number_2)
    number_1_shu=0
    number_2_shu=0
    if '.' in number_1_list:
        number_1_shu=float(number_1)
    else:
        try:
            number_1_shu=int(number_1)
        except ValueError:
            number_1_shu=0
    if '.' in number_2_list:
        number_2_shu=float(number_2)
    else:
        try:
            number_2_shu=int(number_2)
        except ValueError:
            number_2_shu=0
    return(number_1_shu,number_2_shu)
def chuling(number_3):
    """除去浮点数后的零"""
    number_3_str=str(number_3)
    if number_3_str[-1]=='0':
        number_3=int(number_3)
    return number_3

次方运算

def chengfang(number_1,number_2):
    """进行各种次方运算,并返回运算结果"""
    number_1,number_2=float(number_1),int(number_2)
    x=1
    for z in range(number_2):
        x=x*number_1
    return x

效果如图:
在这里插入图片描述
如果计算量太大…显示不出结果
在这里插入图片描述

返回和清除

返回上一步:

def button_tui_click(calculator_screen,
gn_button_lei,setting,digital,shu):
    """创建退一格的响应功能"""
    gn_button_lei[4].color=setting.button_chufa_color
    #改变按钮颜色以反馈触发
    if digital.fuhao==' ' and digital.dier==' ' and not shu.rect_chufa:
    #如果运算符和下一排数字未输入,并且等号未被触发则只删除第一排最后一个字符
        digital_list=list(digital.diyi)
        digital_lenth=len(digital_list)
        if digital_lenth>1:
            del digital_list[digital_lenth-1]
        xin="".join(digital_list)
        digital.diyi=xin
        shu.prep_diyi()
    elif digital.fuhao!=' ' and digital.dier==' ' and not shu.rect_chufa:
    #如果运算符已输入,但下一排数字未输入并且没触发等号,则只删除运算符号
        digital.fuhao=' '
        shu.prep_fuhao()
    elif digital.fuhao!=' ' and digital.dier!=' ' and not shu.rect_chufa:
    #如果运算符已输入下一排数字已输入,但没触发等号,则只删除下排数字字符串的最后一个
        digital_list=list(digital.dier)
        digital_lenth=len(digital_list)
        if digital_lenth>1:
            del digital_list[digital_lenth-1]
        xin="".join(digital_list)
        digital.dier=xin
        shu.prep_dier()
    elif digital.fuhao!=' ' and digital.dier!=' ' and shu.rect_chufa:
        fu.calculator_screen_cler(calculator_screen,digital,shu,setting,1)
    #如果等号被触发,则直接全部清除
    if shu.tips:
        shu.tips=False
    #清除提示信息

清除功能,有两部分组成,一种只清除除第一排数字的所有内容(用于在等号已被触发时再按下数字按钮屏幕会显示新数字,其他清除),另一种则全部清除(一键清除):

def calculator_screen_cler(calculator_screen,
digital,shu,setting,panduan):
    """清空计算器屏幕上的所有信息"""
    if panduan==1:
        digital.chushihua()
        shu.prep_dier()
        shu.prep_fuhao()
        shu.prep_diyi()
        shu.prep_daan()
        shu.rect_chufa=False
        shu.rect_color=setting.calculator_screen_color
    elif panduan==2:
        digital.dier=' '
        digital.daan=' '
        shu.rect_chufa=False
        shu.rect_color=setting.calculator_screen_color
        shu.prep_fuhao()
        shu.prep_diyi()
        shu.prep_dier()
        shu.prep_daan()

自定义设置

之前将所有参数全部集中在一起

import json

class Settings():
    """保存所有设置"""
    def __init__(self):
        #主屏幕参数
        self.screen_width=300
        self.screen_height=500
        #计算器屏幕参数
        self.calculator_screen_width=270
        self.calculator_screen_height=150
        #计算器数字按钮参数
        self.button_jianju=10
        self.button_width=int(((self.screen_width-(self.screen_width-self.calculator_screen_width))-3*self.button_jianju)/4)
        self.button_height=int((self.screen_height-self.calculator_screen_height-6*self.button_jianju)/6)
        self.button_ziti_size=40
        self.digital_size=30
        self.fuhao_size=30
        #计算器导入导出按钮参数
        self.daoru_width=50
        self.daoru_height=20
        self.daoru_ziti_size=20
        #加载用户自定义参数设置
        try:
            path=('./用户自定义.json')
            with open(path,'r') as f:
                list_4=json.load(f)
            self.bg_color=list_4[0]
            self.calculator_screen_color=list_4[1]
            self.digital_color=list_4[2]
            self.fuhao_color=list_4[3]
            self.button_ziti_color=list_4[4]
            self.button_color=list_4[5]
            self.gnbutton_ziti_color=list_4[6]
            self.gnbutton_color=list_4[7]
            self.deng_text_color=list_4[8]
            self.deng_color=list_4[9]
            self.daoru_ziti_color=list_4[10]
            self.daoru_color=list_4[11]
            self.warning_color=list_4[12]
            self.button_chufa_color=list_4[13]
            self.daoru_chufa_color=list_4[14]
            self.rectangle_chufa_color=list_4[15]
            self.tixing_chufa_color=list_4[16]
            self.deng_chufa_color=list_4[17]
        except FileNotFoundError:
            #计算器所有功能的颜色默认参数
            self.bg_color=(200,200,200)
            self.calculator_screen_color=(255,255,255)
            self.digital_color=(0,0,0)
            self.fuhao_color=(255,0,0)
            self.button_ziti_color=(255,0,0)
            self.button_color=(255,255,255)
            self.gnbutton_ziti_color=(255,255,255)
            self.gnbutton_color=(255,0,0)
            self.deng_text_color=(0,0,0)
            self.deng_color=(255,255,255)
            self.daoru_ziti_color=(255,0,0)
            self.daoru_color=(255,255,255)
            self.warning_color=(255,0,0)
            self.button_chufa_color=(0,0,0)
            self.daoru_chufa_color=(0,0,0)
            self.rectangle_chufa_color=(0,0,0)
            self.tixing_chufa_color=(255,0,0)
            self.deng_chufa_color=(0,0,255)
        #将计算器所有颜色参数储存在列表中
        self.list_shu=[self.bg_color,self.calculator_screen_color,self.digital_color,self.fuhao_color,
        self.button_ziti_color,self.button_color,self.gnbutton_ziti_color,self.gnbutton_color,self.deng_text_color,
        self.deng_color,self.daoru_ziti_color,self.daoru_color,self.warning_color,self.button_chufa_color,
        self.daoru_chufa_color,self.rectangle_chufa_color,self.tixing_chufa_color,self.deng_chufa_color]

加入信息说明

    def zidian(self):
        """将颜色参数储存在字典中"""
        self.list_ming=['计算器背景颜色','计算器屏幕颜色','计算器屏幕数字颜色','特殊符号颜色','数字按钮字体颜色',
        '数字按钮颜色','功能按钮字体颜色','功能按钮颜色','等号字体的颜色','等号按钮的颜色','导入导出字体颜色',
        '导入导出按钮颜色','系统警告字体颜色','数字按钮触发反馈颜色','导入导出触发反馈颜色','横线等号触发显示颜色',
        '提示信息触发显示颜色','等号触发反馈颜色']
        self.xinxi={}
        for x in range(len(self.list_ming)):
            self.xinxi[self.list_ming[x]]=self.list_shu[x]
        self.introducion='计算器快捷键说明:\n按‘esc’键退出计算器\n按数字键输入数据\n'\
        '按方向键↑输入乘号\n按方向键↓输入除号\n按方向键→输入加号\n按方向键←输入减号\n'\
        '按’,‘输入负号\n按’.‘输入小数点\n按空格清空屏幕\n按‘Backspace’返回上一步\n'\
        '按左shift输入乘方符号\n按F1导入计算器参数\n按F2导出计算器参数'        

一键导出:
在这里插入图片描述
在这里插入图片描述
然后导入:
在这里插入图片描述

def button_deng_click(gn_button_lei,setting,digital,shu,tips):
    """创建等号功能的响应事件"""
    if digital.diyi!=' ' and digital.dier!=' ':
        gn_button_lei[7].color=setting.deng_chufa_color
        number_1=digital.diyi.strip()
        number_2=digital.dier.strip()
        fuhao=digital.fuhao
        result=fu.jisuan(number_1,number_2,fuhao)
        digital.daan=str(result)
        if tips.neirong!='未显示全部结果!':
            tips.neirong='未显示全部结果!'
        shu.prep_daan()
        shu.rect_color=setting.rectangle_chufa_color
        shu.rect_chufa=True
        tips.draw_tips()

def daochu_click(setting,daoru_lei,tips,shu):
    """响应导出功能的响应事件"""
    daoru_lei[1].color=setting.daoru_chufa_color
    tips.neirong='已导出功能参数!'
    shu.tips=True
    tips.draw_tips()
    setting.zidian()
    path=('./计算器参数.txt')
    with open(path,'w',encoding='utf8') as f:
        f.write('计算器颜色参数(可任意修改):\n')
        for k,v in setting.xinxi.items():
            x=k+' = '+str(v)+'\n'
            f.write(x)
        f.write('\n'+setting.introducion)
    
def daoru_click(setting,daoru_lei ):
    """响应导入功能的响应事件"""
    daoru_lei[0].color=setting.daoru_chufa_color
    path=('./计算器参数.txt')
    list_1=[]
    try:
        with open(path,'r',encoding='utf8') as f:
            list_1=f.readlines()
        list_2=[]
        list_3=[]
        for x in list_1[1:19]:
            y=x.strip().split(' = ')
            list_2.append(y[1])
        for x in list_2:
            x=x.replace('(','').replace(')','')
            y=x.split(',')
            try:
                y[0]=int(y[0].replace('[','').strip())
                y[1]=int(y[1].strip())
                y[2]=int(y[2].replace(']','').strip())
                x=tuple(y)
            except ValueError:
                pass
            list_3.append(x)
        setting.bg_color=list_3[0]
        setting.calculator_screen_color=list_3[1]
        setting.digital_color=list_3[2]
        setting.fuhao_color=list_3[3]
        setting.button_ziti_color=list_3[4]
        setting.button_color=list_3[5]
        setting.gnbutton_ziti_color=list_3[6]
        setting.gnbutton_color=list_3[7]
        setting.deng_text_color=list_3[8]
        setting.deng_color=list_3[9]
        setting.daoru_ziti_color=list_3[10]
        setting.daoru_color=list_3[11]
        setting.warning_color=list_3[12]
        setting.button_chufa_color=list_3[13]
        setting.daoru_chufa_color=list_3[14]
        setting.rectangle_chufa_color=list_3[15]
        setting.tixing_chufa_color=list_3[16]
        setting.deng_chufa_color=list_3[17]
        list_4=[setting.bg_color,setting.calculator_screen_color,
        setting.digital_color,setting.fuhao_color,setting.button_ziti_color,
        setting.button_color,setting.gnbutton_ziti_color,setting.gnbutton_color,
        setting.deng_text_color,setting.deng_color,setting.daoru_ziti_color,
        setting.daoru_color,setting.warning_color,setting.button_chufa_color,
        setting.daoru_chufa_color,setting.rectangle_chufa_color,setting.tixing_chufa_color,
        setting.deng_chufa_color]
        #将修改后的参数储存再一个列表中
        path=('./用户自定义.json')
        with open(path,'w') as f:
            json.dump(list_4,f)
        #将自定义后的参数储存在JSON文件中,下一次打开会直接加载修改后的内容
    except FileNotFoundError:
        pass
  • 4
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值