WHCSRL 技术网

基于Python实现仿Windows标准计算器

  文章背景    

        本人已完成仿Windows简易计算器的项目,就想着完成Windows标准计算器。最近,在知乎里发现用Python做一个计算器这篇文章。这篇文章内容就阐述了基于Python实现标准计算器,本人只需稍加修改就行。

成果展示

Windows标准计算器

 项目成果图

        项目最后成果虽然并不美观,但是和Windows标准计算器布局类似。往后,会完善这个项目。

项目结构

        本人根据项目功能,分为

  • Init.py为计算器初始化文件
  • Function.py为计算器逻辑功能文件
  • Style.py为计算器布局文件
  • main.py为计算器启动文件

 项目结构图

 

 项目代码

Init.py

  1. import math
  2. import tkinter
  3. root = tkinter.Tk()
  4. root.resizable(width=False, height=False)
  5. #是否按下了运算符
  6. IS_CALC = False
  7. #存储数字
  8. STORAGE = []
  9. #显示框最多显示多少个字符
  10. MAXSHOWLEN = 18
  11. #当前显示的数字
  12. CurrentShow = tkinter.StringVar()
  13. CurrentShow.set('0')

Function.py

  1. from Init import *
  2. #按下数字键(0-9)#
  3. def pressNumber(number):
  4. global IS_CALC
  5. if IS_CALC:
  6. CurrentShow.set('0')
  7. IS_CALC = False
  8. if CurrentShow.get() == '0':
  9. CurrentShow.set(number)
  10. else:
  11. if len(CurrentShow.get()) < MAXSHOWLEN:
  12. CurrentShow.set(CurrentShow.get() + number)
  13. #按下小数点#
  14. def pressDP():
  15. global IS_CALC
  16. if IS_CALC:
  17. CurrentShow.set('0')
  18. IS_CALC = False
  19. if len(CurrentShow.get().split('.')) == 1:
  20. if len(CurrentShow.get()) < MAXSHOWLEN:
  21. CurrentShow.set(CurrentShow.get() + '.')
  22. #清零#
  23. def clearAll():
  24. global STORAGE
  25. global IS_CALC
  26. STORAGE.clear()
  27. IS_CALC = False
  28. CurrentShow.set('0')
  29. #清除当前显示框内所有数字#
  30. def clearCurrent():
  31. CurrentShow.set('0')
  32. #删除显示框内最后一个数字#
  33. def delOne():
  34. global IS_CALC
  35. if IS_CALC:
  36. CurrentShow.set('0')
  37. IS_CALC = False
  38. if CurrentShow.get() != '0':
  39. if len(CurrentShow.get()) > 1:
  40. CurrentShow.set(CurrentShow.get()[:-1])
  41. else:
  42. CurrentShow.set('0')
  43. #计算答案修正#
  44. def modifyResult(result):
  45. result = str(result)
  46. if len(result) > MAXSHOWLEN:
  47. if len(result.split('.')[0]) > MAXSHOWLEN:
  48. result = 'Overflow'
  49. else:
  50. # 直接舍去不考虑四舍五入问题
  51. result = result[:MAXSHOWLEN]
  52. return result
  53. #按下运算符#
  54. def pressOperator(operator):
  55. global STORAGE
  56. global IS_CALC
  57. if operator == '+/-':
  58. if CurrentShow.get().startswith('-'):
  59. CurrentShow.set(CurrentShow.get()[1:])
  60. else:
  61. CurrentShow.set('-'+CurrentShow.get())
  62. elif operator == '1/x':
  63. try:
  64. result = 1 / float(CurrentShow.get())
  65. except:
  66. result = 'illegal operation'
  67. result = modifyResult(result)
  68. CurrentShow.set(result)
  69. IS_CALC = True
  70. elif operator == 'sqrt':
  71. try:
  72. result = math.sqrt(float(CurrentShow.get()))
  73. except:
  74. result = 'illegal operation'
  75. result = modifyResult(result)
  76. CurrentShow.set(result)
  77. IS_CALC = True
  78. elif operator=='x²':
  79. result=int(math.pow(int(CurrentShow.get()),2))
  80. result = modifyResult(result)
  81. CurrentShow.set(result)
  82. IS_CALC = True
  83. elif operator == 'MC':
  84. STORAGE.clear()
  85. elif operator == 'MR':
  86. if IS_CALC:
  87. CurrentShow.set('0')
  88. STORAGE.append(CurrentShow.get())
  89. expression = ''.join(STORAGE)
  90. try:
  91. result = eval(expression)
  92. except:
  93. result = 'illegal operation'
  94. result = modifyResult(result)
  95. CurrentShow.set(result)
  96. IS_CALC = True
  97. elif operator == 'MS':
  98. STORAGE.clear()
  99. STORAGE.append(CurrentShow.get())
  100. elif operator == 'M+':
  101. STORAGE.append(CurrentShow.get())
  102. elif operator == 'M-':
  103. if CurrentShow.get().startswith('-'):
  104. STORAGE.append(CurrentShow.get())
  105. else:
  106. STORAGE.append('-' + CurrentShow.get())
  107. elif operator in ['+', '-', '*', '/', '%%']:
  108. STORAGE.append(CurrentShow.get())
  109. STORAGE.append(operator)
  110. IS_CALC = True
  111. elif operator == '=':
  112. if IS_CALC:
  113. CurrentShow.set('0')
  114. STORAGE.append(CurrentShow.get())
  115. expression = ''.join(STORAGE)
  116. try:
  117. result = eval(expression)
  118. # 除以0的情况
  119. except:
  120. result = 'illegal operation'
  121. result = modifyResult(result)
  122. CurrentShow.set(result)
  123. STORAGE.clear()
  124. IS_CALC = True

Style.py

  1. from Init import *
  2. from Function import *
  3. def Demo():
  4. root.minsize(320, 420)
  5. root.title('Calculator')
  6. # 布局
  7. # --文本框
  8. label = tkinter.Label(root, textvariable=CurrentShow, bg='black', anchor='e', bd=5, fg='white', font=('楷体', 20))
  9. label.place(x=20, y=50, width=280, height=50)
  10. # --第一行
  11. # ----Memory clear
  12. button1_1 = tkinter.Button(text='MC', bg='#666', bd=2, command=lambda:pressOperator('MC'))
  13. button1_1.place(x=20, y=110, width=50, height=35)
  14. # ----Memory read
  15. button1_2 = tkinter.Button(text='MR', bg='#666', bd=2, command=lambda:pressOperator('MR'))
  16. button1_2.place(x=77.5, y=110, width=50, height=35)
  17. # ----Memory +
  18. button1_3 = tkinter.Button(text='M+', bg='#666', bd=2, command=lambda:pressOperator('M+'))
  19. button1_3.place(x=135, y=110, width=50, height=35)
  20. # ----Memory -
  21. button1_4 = tkinter.Button(text='M-', bg='#666', bd=2, command=lambda:pressOperator('M-'))
  22. button1_4.place(x=192.5, y=110, width=50, height=35)
  23. # ----Memory save
  24. button1_5 = tkinter.Button(text='MS', bg='#666', bd=2, command=lambda: pressOperator('MS'))
  25. button1_5.place(x=250, y=110, width=50, height=35)
  26. # --第二行
  27. # ----取余
  28. button2_1 = tkinter.Button(text='%%', bg='#708069', bd=2, command=lambda:pressOperator('%%'))
  29. button2_1.place(x=20, y=155, width=62.5, height=35)
  30. # ----清除当前显示框内所有数字
  31. button2_2 = tkinter.Button(text='CE', bg='#666', bd=2, command=lambda:clearCurrent())
  32. button2_2.place(x=77.5, y=155, width=62.5, height=35)
  33. # ----清零(相当于重启)
  34. button2_3 = tkinter.Button(text='C', bg='#666', bd=2, command=lambda: clearAll())
  35. button2_3.place(x=135, y=155, width=62.5, height=35)
  36. # ----删除单个数字
  37. button2_4 = tkinter.Button(text='del', bg='#666', bd=2, command=lambda:delOne())
  38. button2_4.place(x=192.5, y=155, width=62.5, height=35)
  39. # --第三行
  40. # ----取导数
  41. button3_1 = tkinter.Button(text='1/x', bg='#708069', bd=2, command=lambda: pressOperator('1/x'))
  42. button3_1.place(x=20, y=190, width=62.5, height=35)
  43. # ----平方
  44. button3_2 = tkinter.Button(text='x²', bg='#708069', bd=2, command=lambda: pressOperator('x²'))
  45. button3_2.place(x=77.5, y=190, width=62.5, height=35)
  46. # ----开根号
  47. button3_3 = tkinter.Button(text='sqrt', bg='#666', bd=2, command=lambda:pressOperator('sqrt'))
  48. button3_3.place(x=135, y=190, width=62.5, height=35)
  49. # ----除
  50. button3_4 = tkinter.Button(text='/', bg='#708069', bd=2, command=lambda: pressOperator('/'))
  51. button3_4.place(x=192.5, y=190, width=62.5, height=35)
  52. # --第四行
  53. # ----7
  54. button4_1 = tkinter.Button(text='7', bg='#bbbbbb', bd=2, command=lambda:pressNumber('7'))
  55. button4_1.place(x=20, y=225, width=62.5, height=35)
  56. # ----8
  57. button4_2 = tkinter.Button(text='8', bg='#bbbbbb', bd=2, command=lambda:pressNumber('8'))
  58. button4_2.place(x=77.5, y=225, width=62.5, height=35)
  59. # ----9
  60. button4_3 = tkinter.Button(text='9', bg='#bbbbbb', bd=2, command=lambda:pressNumber('9'))
  61. button4_3.place(x=135, y=225, width=62.5, height=35)
  62. # ----乘
  63. button4_4 = tkinter.Button(text='*', bg='#708069', bd=2, command=lambda: pressOperator('*'))
  64. button4_4.place(x=192.5, y=225, width=62.5, height=35)
  65. # --第五行
  66. # ----4
  67. button5_1 = tkinter.Button(text='4', bg='#bbbbbb', bd=2, command=lambda:pressNumber('4'))
  68. button5_1.place(x=20, y=265, width=62.5, height=35)
  69. # ----5
  70. button5_2 = tkinter.Button(text='5', bg='#bbbbbb', bd=2, command=lambda:pressNumber('5'))
  71. button5_2.place(x=77.5, y=265, width=62.5, height=35)
  72. # ----6
  73. button5_3 = tkinter.Button(text='6', bg='#bbbbbb', bd=2, command=lambda:pressNumber('6'))
  74. button5_3.place(x=135, y=265, width=62.5, height=35)
  75. # ----减
  76. button5_4 = tkinter.Button(text='-', bg='#708069', bd=2, command=lambda: pressOperator('-'))
  77. button5_4.place(x=192.5, y=265, width=62.5, height=35)
  78. # --第六行
  79. # ----1
  80. button6_1 = tkinter.Button(text='1', bg='#bbbbbb', bd=2, command=lambda: pressNumber('1'))
  81. button6_1.place(x=20, y=300, width=62.5, height=35)
  82. # ----2
  83. button6_2 = tkinter.Button(text='2', bg='#bbbbbb', bd=2, command=lambda: pressNumber('2'))
  84. button6_2.place(x=77.5, y=300, width=62.5, height=35)
  85. # ----3
  86. button6_3 = tkinter.Button(text='3', bg='#bbbbbb', bd=2, command=lambda:pressNumber('3'))
  87. button6_3.place(x=135, y=300, width=62.5, height=35)
  88. # ----加
  89. button6_4 = tkinter.Button(text='+', bg='#708069', bd=2, command=lambda: pressOperator('+'))
  90. button6_4.place(x=192.5, y=300, width=62.5, height=35)
  91. # --第七行
  92. # ----0
  93. # ----取反
  94. button7_1 = tkinter.Button(text='+/-', bg='#666', bd=2, command=lambda: pressOperator('+/-'))
  95. button7_1.place(x=20, y=345, width=62.5, height=35)
  96. button7_2 = tkinter.Button(text='0', bg='#bbbbbb', bd=2, command=lambda:pressNumber('0'))
  97. button7_2.place(x=77.5, y=345, width=62.5, height=35)
  98. # ----小数点
  99. button7_3 = tkinter.Button(text='.', bg='#bbbbbb', bd=2, command=lambda:pressDP())
  100. button7_3.place(x=135, y=345, width=62.5, height=35)
  101. # ----等于
  102. button7_4 = tkinter.Button(text='=', bg='#708069', bd=2, command=lambda: pressOperator('='))
  103. button7_4.place(x=192.5, y=345, width=62.5, height=35)
  104. root.mainloop()

main.py

  1. from Init import *
  2. from Style import *
  3. if __name__ == '__main__':
  4. Demo()

温馨提示

          若有求源码的需求,或复制时代码出现问题需要解答的人,可用QQ/Wechat:921899847联系。添加好友时,请备注:需代码支援。

推荐阅读