|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
创作背景
很久以前学习了 tkinter 的一个计算器,便引发了我的热爱,为那个极其简单的计算器加上了很多功能。
而今天这个则是进行了一番大改,代码没时间细讲,大家可以看注释
往期版本
超厉害的Python ttkbootstrap计算器(原创)(甚至还教你图片处理)
Python 计算器图片(原创)(太炸裂了)
注意事项
需要用到两张图片(ico图标和等于号) 大家可以自行换上自己喜欢的图片
代码思路
精华是 eval() 和 Decimal 。这次加上的 input_list 也升华了整个作品~
支持鼠标点击和键盘输入(非常神奇)
其中键盘输入 删除,回车,C,c 有奇效
还支持某些(奇怪)的运算,如:√√√256(就是2)
球评分~
- """
- frame框架布局
- 在frame内部,可以重新进行一次布局
- """
- import ttkbootstrap as ttk
- from ttkbootstrap.constants import *
- from PIL import ImageTk, Image
- from decimal import Decimal
- from math import sqrt
- def top1():
- top = ttk.Toplevel(title="详情")
- label = ttk.Label(master=top, text="""
- 全FishC最好的计算器!\n
- 消除误差!0.1+0.2可以等于0.3!
- 过大或过小的数值会用科学计数法\n
- 注意:
- π取3.1415926,根号运算取7位小数,
- 支持鼠标点击和键盘输入(非常神奇)
- 其中键盘输入 删除,回车,C,c 有奇效\n
- 还支持某些(奇怪)的运算,如:√√√256(就是2)
- """)
- label.pack()
- def top2():
- top = ttk.Toplevel(title="作者")
- label = ttk.Label(master=top, text="""
- 作者:FishC 某一个“天”
- ~谢谢使用~
- """)
- label.pack()
- def top3():
- top = ttk.Toplevel(title="历史记录")
- label = ttk.Label(master=top, text="".join(history_input_list))
- label.pack()
- win = ttk.Window()
- win.title("FishC最好的?计算器")
- win.geometry("360x364+500+200")
- win.resizable(width=False, height=False) # 设置不能调整窗口大小
- # 设置窗体图标
- win.iconbitmap("./py_pic/jsq3.ico")
- # 创建菜单栏
- menu_bar = ttk.Menu(win)
- win.config(menu=menu_bar)
- # 创建菜单项
- info_menu = ttk.Menu(menu_bar, tearoff=False)
- info_menu.add_command(label="详情", command=top1)
- info_menu.add_command(label="作者", command=top2)
- menu_bar.add_cascade(label="关于计算器", menu=info_menu)
- history_menu = ttk.Menu(menu_bar, tearoff=False)
- history_menu.add_command(label="查看", command=top3)
- history_menu.add_command(label="清空", command=lambda: history_input_list.clear())
- menu_bar.add_cascade(label="历史记录", menu=history_menu)
- style = ttk.Style()
- style.configure("TButton", font=("微软雅黑", 15))
- history_input_list = []
- input_list = []
- def my_sqrt(x):
- return Decimal(Decimal(sqrt(x))).quantize(Decimal("0.0000000"))
- def clear():
- input_list.clear()
- varLabel0.set("计算过程区:")
- varEntry0.set("")
- def is_old_entry_part(txt):
- global input_list
- if "=" in varEntry0.get() or varEntry0.get() == "错误": # 新的算式
- input_list = [txt]
- varLabel0.set("计算过程区:")
- varEntry0.set(txt)
- return False
- return True
- def calcu(event, is_key=False):
- global input_list
- # 判断输入方式
- if is_key:
- txt = event.char
- print("-------", txt)
- if txt == "\x08": # 删除键
- input_list = input_list[:-1]
- elif txt == "\r": # 回车键
- varLabel0.set("")
- theEqual_Click()
- elif txt in ("c", "C"): # 清空
- clear()
- return "break" # 取消本次输入
- else:
- if is_old_entry_part(txt):
- input_list.append(txt)
- else:
- txt = str(event.widget["text"])
- if txt == "取余":
- txt = "%"
- elif txt == "整除":
- txt = "//"
- elif txt == "x^y":
- txt = "**"
- elif txt == "√x":
- txt = "√"
- if txt == "00":
- input_list.append("0")
- input_list.append("0")
- else:
- input_list.append(txt)
- print(input_list)
- def fast_add(master, text=txt):
- master.set(master.get() + text)
- # 防止输入过长
- if len(varEntry0.get()) < 28 or txt == "C" or txt == "CE":
- if txt == "C": # 清空
- clear()
- elif txt == "CE":
- del input_list[-2:]
- if varEntry0.get() and "=" not in varEntry0.get():
- if varEntry0.get()[-2:] in ("**", "//"):
- varEntry0.set(varEntry0.get()[:-2])
- else:
- varEntry0.set(varEntry0.get()[:-1])
- elif "=" not in varEntry0.get():
- if varLabel0.get()[-2:] in ("**", "//"):
- varLabel0.set(varLabel0.get()[:-2])
- else:
- varLabel0.set(varLabel0.get()[:-1])
- elif txt == "π":
- try:
- if is_old_entry_part(txt):
- fast_add(varEntry0)
- # 有 IndexError: list index out of range 的危险
- if input_list[-2] in ("π", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"):
- input_list.insert(-1, "*")
- except Exception as e:
- print(e)
- elif txt == "√":
- if is_old_entry_part(txt):
- fast_add(varEntry0)
- elif txt in ("+", "-", "*", "/", "%", "//", "**"):
- if "=" in varEntry0.get():
- input_list = [get_result(input_list[:-1])]
- varEntry0.set("")
- varLabel0.set(get_result(input_list) + txt)
- input_list.append(txt)
- elif ("+" in varLabel0.get() or "-" in varLabel0.get() or
- "*" in varLabel0.get() or "/" in varLabel0.get() or
- "%" in varLabel0.get() or "//" in varLabel0.get() or
- "**" in varLabel0.get()):
- # 考虑到运算顺序
- if (txt in ("+", "-") or "**" in varEntry0.get()) and "(" not in varEntry0.get():
- try:
- res = get_result(input_list[:-1])
- varLabel0.set(res + txt)
- input_list = [res, txt]
- varEntry0.set("")
- except Exception as e:
- print(e)
- input_list.pop() # 删掉错误信息
- varEntry0.set("错误")
- else:
- varLabel0.set(varLabel0.get() + varEntry0.get() + txt)
- varEntry0.set("")
- else:
- if "(" in varEntry0.get() and ")" not in varEntry0.get(): # 分行
- fast_add(varEntry0) # 正常输入
- else:
- if "√" in varEntry0.get():
- varEntry0.set(get_result(input_list[:-1]) + txt)
- else:
- varLabel0.set(varEntry0.get() + txt)
- varEntry0.set("")
- else:
- if is_old_entry_part(txt):
- fast_add(varEntry0) # 正常输入数字的情况
- def split_list(lst, *delimiter):
- result = []
- current_part = []
- have_right_bracket = 0
- for item in lst:
- if item == ")":
- have_right_bracket += 1
- elif item == "√":
- current_part.append("my_sqrt(")
- have_right_bracket += 1
- elif item == "π":
- current_part.append("3.1415926")
- if item in delimiter:
- if current_part: # 确保当前部分不为空
- result.append(current_part)
- current_part = []
- while have_right_bracket and item != "(":
- result.append(")")
- have_right_bracket -= 1
- result.append(item)
- # 可能出现在开头的
- elif item in ("-", "("):
- result.append(item)
- elif item not in ("√", ")", "π"):
- current_part.append(item)
- if current_part: # 添加最后一部分(如果存在)
- while have_right_bracket:
- current_part.append(")")
- have_right_bracket -= 1
- result.append(current_part)
- return result
- def get_result(lst):
- split_result = split_list(lst, "(", "+", "-", "*", "/", "%", "//", "**")
- split_result = ["".join(i) for i in split_result]
- index = 0
- for each in split_result:
- try:
- split_result[index] = repr(Decimal(each))
- except Exception as e:
- print(e)
- print(split_result)
- index += 1
- result = str(eval("".join(split_result)))
- history_input_list.extend(["".join(input_list), "=", result, "\n"])
- return result
- def theEqual_Click():
- try:
- result = get_result(input_list)
- print(result)
- varLabel0.set(varLabel0.get()+varEntry0.get())
- varEntry0.set("=" + result)
- except Exception as e:
- print(e)
- varEntry0.set("错误")
- # 显示结果部分
- varLabel0 = ttk.StringVar()
- varLabel0.set("计算过程区:")
- label0 = ttk.Label(win, font=("宋体", 15), textvariable=varLabel0)
- label0.grid(sticky=ttk.EW) # 东西方向填充
- varEntry0 = ttk.StringVar()
- entry0 = ttk.Entry(win, font=("微软雅黑", 15), textvariable=varEntry0)
- entry0.grid(sticky=ttk.EW) # 东西方向填充
- entry0.bind("<Key>", lambda event: calcu(event, True)) # 绑定键盘事件
- # 按钮部分
- # 创建frame框架
- box = ttk.Frame(win)
- box.grid(row=2, column=0)
- # 按钮文本的列表
- btnText = ["(", ")", "x^y", "√x", "π",
- "7", "8", "9", "*", "/",
- "4", "5", "6", "+", "-",
- "1", "2", "3", "取余", "整除",
- "0", "00", ".", "C", "CE"]
- # 行和列
- ri = 0
- ci = 0
- # 通过循环批量制作按钮
- for v in btnText:
- if ci != 0 and ci % 5 == 0:
- ri += 1 # 换行
- ci = 0 # 列变为0
- '''单击事件绑定
- 1.command只能绑定一个,如果要传参可以用lambda表达式
- 2.bind可以传当前控件事件到自定义函数'''
- btn1 = ttk.Button(box, text=v, width=4, bootstyle=(SUCCESS, OUTLINE))
- btn1.bind("<Button-1>", calcu) # 左键单击事件
- btn1.grid(row=ri, column=ci, rowspan=1)
- ci += 1
- # =
- pic_equal = Image.open("./py_pic/等于号.png") # 载入图片对象
- pic_equal = pic_equal.resize((225, 60)) # 一个元组
- pic_equal = ImageTk.PhotoImage(pic_equal) # 变成适合ttk的图片格式
- btnEqual = ttk.Button(box, image=pic_equal, command=theEqual_Click, style='warning-solid')
- btnEqual.grid(row=ri + 1, column=0, columnspan=5, sticky=ttk.EW)
- win.mainloop()
复制代码
@isdkz @ba21 @KeyError @zhangjinxuan @sfqxx @不二如是 @python爱好者. @小甲鱼的三师弟 @sfqxx_小 @柿子饼同学 @陈尚涵
大家帮忙@一点人
|
评分
-
查看全部评分
|