代码拉取完成,页面将自动刷新
import tkinter as tk
from tkinter import ttk, messagebox
import math
import re
# ==================== 安全计算环境 ====================
# 构建安全的数学函数字典
safe_dict = {
'acos': math.acos,
'asin': math.asin,
'atan': math.atan,
'atan2': math.atan2,
'ceil': math.ceil,
'cos': math.cos,
'cosh': math.cosh,
'degrees': math.degrees,
'exp': math.exp,
'fabs': math.fabs,
'floor': math.floor,
'fmod': math.fmod,
'frexp': math.frexp,
'hypot': math.hypot,
'ldexp': math.ldexp,
'log': math.log,
'log10': math.log10,
'modf': math.modf,
'pow': math.pow,
'radians': math.radians,
'sin': math.sin,
'sinh': math.sinh,
'sqrt': math.sqrt,
'tan': math.tan,
'tanh': math.tanh,
'pi': math.pi,
'e': math.e,
'tau': math.tau,
'factorial': math.factorial,
'gcd': math.gcd,
'isclose': math.isclose,
'isfinite': math.isfinite,
'isinf': math.isinf,
'isnan': math.isnan,
'trunc': math.trunc,
}
# 添加常用别名
safe_dict['ln'] = math.log
safe_dict['lg'] = math.log10
safe_dict['arcsin'] = math.asin
safe_dict['arccos'] = math.acos
safe_dict['arctan'] = math.atan
def safe_eval(expr: str) -> float:
"""安全地计算数学表达式"""
# 预处理:将 ^ 替换为 **
expr = expr.replace('^', '**')
# 允许中文括号转换
expr = expr.replace('(', '(').replace(')', ')')
# 去除空白
expr = expr.strip()
if not expr:
raise ValueError("空表达式")
# 检查危险字符(只允许数字、运算符、字母、括号、小数点、逗号、空格)
if not re.match(r'^[\d\s\+\-\*\/\%\(\)\^\,\|\&\~\!\<\>\=\.\w]+$', expr):
# 更严格的检查:禁止双下划线、import、exec等
if '__' in expr or 'import' in expr or 'exec' in expr or 'eval' in expr:
raise ValueError("非法表达式")
# 使用限制的命名空间求值
result = eval(expr, {"__builtins__": None}, safe_dict)
# 确保结果是数字
if isinstance(result, (int, float, complex)) and not isinstance(result, complex):
return float(result)
else:
raise ValueError("结果不是实数")
# ==================== 炫酷计算器主类 ====================
class SuperCoolCalculator:
def __init__(self, root):
self.root = root
self.root.title("⚡ 超级炸裂炫酷计算器 ⚡")
self.root.geometry("1100x750")
self.root.resizable(True, True)
self.root.configure(bg='#0a0f1a')
# 存储变量
self.memory = 0.0 # 记忆存储
self.current_mode = "RAD" # 角度模式 RAD/DEG
self.history_list = [] # 历史记录
# 设置炫酷样式
self.setup_styles()
# 创建UI组件
self.create_widgets()
# 绑定键盘事件
self.bind_keys()
# 启动闪烁效果
self.blink_effect()
def setup_styles(self):
"""配置炫酷颜色和字体"""
# 颜色方案:霓虹暗黑
self.colors = {
'bg': '#0a0f1a', # 主背景深蓝黑
'display_bg': '#010101', # 显示屏纯黑
'display_fg': '#00ffcc', # 霓虹青
'btn_num': '#1e2a3a', # 数字按钮深蓝灰
'btn_op': '#2a1e3a', # 运算符暗紫
'btn_func': '#1a3a2a', # 函数暗绿
'btn_mem': '#3a1e2a', # 记忆暗红
'btn_eq': '#00aa88', # 等号霓虹绿
'btn_clear': '#aa3355', # 清除炫粉
'hover': '#00ffcc', # 悬停亮色
'text': '#ccfffc', # 文字亮青
'history_bg': '#0d1520',
'history_fg': '#88ffdd'
}
# 自定义字体
self.font_display = ('Courier New', 24, 'bold')
self.font_button = ('Segoe UI', 12, 'bold')
self.font_history = ('Consolas', 10)
# 设置窗口背景
self.root.configure(bg=self.colors['bg'])
def create_widgets(self):
# 主框架
main_frame = tk.Frame(self.root, bg=self.colors['bg'])
main_frame.pack(fill=tk.BOTH, expand=True, padx=15, pady=15)
# ========== 显示区域 ==========
display_frame = tk.Frame(main_frame, bg=self.colors['bg'])
display_frame.pack(fill=tk.X, pady=(0, 10))
# 表达式输入框(可编辑)
self.expr_var = tk.StringVar()
self.entry = tk.Entry(
display_frame, textvariable=self.expr_var,
font=self.font_display, bg=self.colors['display_bg'],
fg=self.colors['display_fg'], insertbackground='#00ffcc',
relief=tk.FLAT, highlightthickness=2, highlightcolor=self.colors['hover'],
highlightbackground='#1a2a3a', bd=0
)
self.entry.pack(fill=tk.X, ipady=12, pady=(0, 8))
self.entry.focus_set()
# 绑定回车键计算
self.entry.bind('<Return>', lambda e: self.calculate())
# 状态栏(角度模式+记忆指示)
status_frame = tk.Frame(display_frame, bg=self.colors['bg'])
status_frame.pack(fill=tk.X)
self.mode_label = tk.Label(
status_frame, text=f"模式: {self.current_mode}", fg='#ffaa66',
bg=self.colors['bg'], font=('Segoe UI', 9, 'bold')
)
self.mode_label.pack(side=tk.LEFT, padx=5)
self.mem_label = tk.Label(
status_frame, text="M: 0", fg='#ff66aa',
bg=self.colors['bg'], font=('Segoe UI', 9, 'bold')
)
self.mem_label.pack(side=tk.RIGHT, padx=5)
# ========== 左右分区:左边数字/运算符,右边科学函数 ==========
split_frame = tk.Frame(main_frame, bg=self.colors['bg'])
split_frame.pack(fill=tk.BOTH, expand=True)
# 左侧面板 (基础运算)
left_frame = tk.Frame(split_frame, bg=self.colors['bg'])
left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 10))
# 右侧面板 (科学函数/常数)
right_frame = tk.Frame(split_frame, bg=self.colors['bg'])
right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
# ========== 左侧按钮区域 ==========
# 记忆功能区
mem_buttons = [
('MC', self.mem_clear), ('MR', self.mem_recall),
('M+', self.mem_add), ('M-', self.mem_sub)
]
mem_frame = tk.Frame(left_frame, bg=self.colors['bg'])
mem_frame.pack(fill=tk.X, pady=5)
for text, cmd in mem_buttons:
btn = self.create_cool_button(mem_frame, text, cmd, 'mem', width=6)
btn.pack(side=tk.LEFT, padx=2, expand=True, fill=tk.X)
# 清除 / 退格 / 进制转换 / 单位换算
func_frame = tk.Frame(left_frame, bg=self.colors['bg'])
func_frame.pack(fill=tk.X, pady=5)
clear_btn = self.create_cool_button(func_frame, "C", self.clear_all, 'clear', width=6)
clear_btn.pack(side=tk.LEFT, padx=2, expand=True, fill=tk.X)
back_btn = self.create_cool_button(func_frame, "⌫", self.backspace, 'func', width=6)
back_btn.pack(side=tk.LEFT, padx=2, expand=True, fill=tk.X)
conv_btn = self.create_cool_button(func_frame, "进制", self.show_converter, 'func', width=6)
conv_btn.pack(side=tk.LEFT, padx=2, expand=True, fill=tk.X)
unit_btn = self.create_cool_button(func_frame, "单位", self.show_unit_converter, 'func', width=6)
unit_btn.pack(side=tk.LEFT, padx=2, expand=True, fill=tk.X)
# 数字和基本运算符网格 (7x5)
left_buttons = [
('7', 'num'), ('8', 'num'), ('9', 'num'), ('/', 'op'), ('(', 'op'),
('4', 'num'), ('5', 'num'), ('6', 'num'), ('*', 'op'), (')', 'op'),
('1', 'num'), ('2', 'num'), ('3', 'num'), ('-', 'op'), ('%', 'op'),
('0', 'num'), ('.', 'num'), ('±', 'func'), ('+', 'op'), ('=', 'eq')
]
# 创建网格布局
grid_frame = tk.Frame(left_frame, bg=self.colors['bg'])
grid_frame.pack(fill=tk.BOTH, expand=True, pady=5)
row, col = 0, 0
for (text, typ) in left_buttons:
if typ == 'eq':
cmd = self.calculate
elif typ == 'func' and text == '±':
cmd = self.negate
else:
cmd = lambda x=text: self.insert_text(x)
btn = self.create_cool_button(grid_frame, text, cmd, typ, width=6)
btn.grid(row=row, column=col, padx=2, pady=4, sticky='nsew')
col += 1
if col > 4:
col = 0
row += 1
# 让网格均匀扩展
for i in range(5):
grid_frame.columnconfigure(i, weight=1)
for i in range(row + 1):
grid_frame.rowconfigure(i, weight=1)
# ========== 右侧科学函数面板 ==========
sci_frame = tk.Frame(right_frame, bg=self.colors['bg'])
sci_frame.pack(fill=tk.BOTH, expand=True)
# 三角函数区
trig_funcs = [
('sin', 'sin('), ('cos', 'cos('), ('tan', 'tan('),
('asin', 'asin('), ('acos', 'acos('), ('atan', 'atan(')
]
trig_label = tk.Label(sci_frame, text="⚡ 三角函数 ⚡", fg='#ffaa88', bg=self.colors['bg'],
font=('Segoe UI', 10, 'bold'))
trig_label.pack(anchor='w', pady=(10, 5))
trig_frame = tk.Frame(sci_frame, bg=self.colors['bg'])
trig_frame.pack(fill=tk.X)
for i, (label, cmd_text) in enumerate(trig_funcs):
btn = self.create_cool_button(trig_frame, label, lambda x=cmd_text: self.insert_text(x), 'func', width=5)
btn.grid(row=i // 3, column=i % 3, padx=2, pady=4, sticky='nsew')
for i in range(3):
trig_frame.columnconfigure(i, weight=1)
# 对数/指数
exp_log = [
('ln', 'ln('), ('log', 'log('), ('lg', 'lg('),
('exp', 'exp('), ('√', 'sqrt('), ('^', '^')
]
exp_label = tk.Label(sci_frame, text="📈 指数 & 对数", fg='#88ffaa', bg=self.colors['bg'],
font=('Segoe UI', 10, 'bold'))
exp_label.pack(anchor='w', pady=(10, 5))
exp_frame = tk.Frame(sci_frame, bg=self.colors['bg'])
exp_frame.pack(fill=tk.X)
for i, (label, cmd_text) in enumerate(exp_log):
btn = self.create_cool_button(exp_frame, label, lambda x=cmd_text: self.insert_text(x), 'func', width=5)
btn.grid(row=i // 3, column=i % 3, padx=2, pady=4, sticky='nsew')
for i in range(3):
exp_frame.columnconfigure(i, weight=1)
# 常数 & 特殊函数
consts = [
('π', 'pi'), ('e', 'e'), ('τ', 'tau'),
('阶乘', 'factorial('), ('取余', '%'), ('幂', '**')
]
const_label = tk.Label(sci_frame, text="🔢 常数 & 运算", fg='#aaffff', bg=self.colors['bg'],
font=('Segoe UI', 10, 'bold'))
const_label.pack(anchor='w', pady=(10, 5))
const_frame = tk.Frame(sci_frame, bg=self.colors['bg'])
const_frame.pack(fill=tk.X)
for i, (label, cmd_text) in enumerate(consts):
btn = self.create_cool_button(const_frame, label, lambda x=cmd_text: self.insert_text(x), 'func', width=5)
btn.grid(row=i // 3, column=i % 3, padx=2, pady=4, sticky='nsew')
for i in range(3):
const_frame.columnconfigure(i, weight=1)
# 角度模式切换
mode_btn = self.create_cool_button(sci_frame, "DEG/RAD", self.toggle_mode, 'func', width=10)
mode_btn.pack(pady=10)
# ========== 历史记录区域 ==========
history_frame = tk.Frame(main_frame, bg=self.colors['bg'])
history_frame.pack(fill=tk.BOTH, expand=False, pady=(10, 0))
hist_title = tk.Label(history_frame, text="📜 历史记录", fg=self.colors['display_fg'],
bg=self.colors['bg'], font=('Segoe UI', 10, 'bold'))
hist_title.pack(anchor='w')
self.history_text = tk.Text(history_frame, height=6, bg=self.colors['history_bg'],
fg=self.colors['history_fg'], font=self.font_history,
relief=tk.FLAT, bd=0, wrap=tk.WORD)
self.history_text.pack(fill=tk.BOTH, expand=True, pady=5)
self.history_text.config(state=tk.DISABLED)
clear_hist_btn = self.create_cool_button(history_frame, "清除历史", self.clear_history, 'mem', width=12)
clear_hist_btn.pack(pady=2)
def create_cool_button(self, parent, text, command, btn_type, width=8):
"""创建炫酷风格的按钮"""
color_map = {
'num': self.colors['btn_num'],
'op': self.colors['btn_op'],
'func': self.colors['btn_func'],
'mem': self.colors['btn_mem'],
'clear': self.colors['btn_clear'],
'eq': self.colors['btn_eq']
}
bg_color = color_map.get(btn_type, self.colors['btn_func'])
fg_color = self.colors['text']
btn = tk.Button(
parent, text=text, command=command,
font=self.font_button, bg=bg_color, fg=fg_color,
relief=tk.RAISED, bd=1, activebackground=self.colors['hover'],
activeforeground='#000000', cursor='hand2', width=width
)
# 悬停特效
def on_enter(e):
btn.config(bg=self.colors['hover'], fg='#000000')
def on_leave(e):
btn.config(bg=bg_color, fg=fg_color)
btn.bind("<Enter>", on_enter)
btn.bind("<Leave>", on_leave)
return btn
def blink_effect(self):
"""霓虹闪烁效果(状态栏颜色变化)"""
current = self.mode_label.cget('fg')
new_color = '#ffcc00' if current == '#ffaa66' else '#ffaa66'
self.mode_label.config(fg=new_color)
self.root.after(800, self.blink_effect)
def insert_text(self, char):
"""向表达式输入框插入字符"""
self.entry.insert(tk.INSERT, char)
self.entry.focus_set()
def clear_all(self):
"""清空表达式"""
self.expr_var.set("")
self.entry.focus_set()
def backspace(self):
"""退格删除"""
current = self.expr_var.get()
self.expr_var.set(current[:-1])
self.entry.focus_set()
def negate(self):
"""取反当前表达式或数字"""
current = self.expr_var.get().strip()
if not current:
self.insert_text("-")
else:
# 简单取反:在表达式前加负号并括号,或者最后数字取反,这里简单处理
self.expr_var.set(f"-({current})")
self.entry.focus_set()
def toggle_mode(self):
"""切换角度/弧度模式"""
if self.current_mode == "RAD":
self.current_mode = "DEG"
self.mode_label.config(text="模式: DEG")
# 修改安全字典中的三角函数为角度版本
for func in ['sin', 'cos', 'tan', 'asin', 'acos', 'atan']:
if func in safe_dict:
original = getattr(math, func)
if self.current_mode == "DEG" and func in ['sin', 'cos', 'tan']:
safe_dict[func] = lambda x, o=original: o(math.radians(x))
elif self.current_mode == "DEG" and func in ['asin', 'acos', 'atan']:
safe_dict[func] = lambda x, o=original: math.degrees(o(x))
else:
safe_dict[func] = original
else:
self.current_mode = "RAD"
self.mode_label.config(text="模式: RAD")
# 恢复标准弧度函数
for func in ['sin', 'cos', 'tan', 'asin', 'acos', 'atan']:
safe_dict[func] = getattr(math, func)
def calculate(self):
"""计算表达式并显示结果"""
expr = self.expr_var.get().strip()
if not expr:
return
try:
# 预处理角度模式的影响(上面已经替换了函数,但直接eval即可)
result = safe_eval(expr)
# 格式化结果
if isinstance(result, float):
if result.is_integer():
result_str = str(int(result))
else:
result_str = f"{result:.10f}".rstrip('0').rstrip('.')
else:
result_str = str(result)
# 更新显示
self.expr_var.set(result_str)
# 添加到历史
history_entry = f"{expr} = {result_str}"
self.history_list.append(history_entry)
self.update_history_display()
except Exception as e:
messagebox.showerror("错误", f"表达式无效:\n{expr}\n错误: {str(e)}")
def update_history_display(self):
"""刷新历史记录显示"""
self.history_text.config(state=tk.NORMAL)
self.history_text.delete(1.0, tk.END)
for line in self.history_list[-20:]: # 只显示最近20条
self.history_text.insert(tk.END, line + "\n")
self.history_text.config(state=tk.DISABLED)
def clear_history(self):
"""清空历史"""
self.history_list.clear()
self.update_history_display()
# 记忆功能
def mem_clear(self):
self.memory = 0.0
self.mem_label.config(text="M: 0")
def mem_recall(self):
self.expr_var.set(str(self.memory))
self.entry.focus_set()
def mem_add(self):
try:
val = safe_eval(self.expr_var.get())
self.memory += val
self.mem_label.config(text=f"M: {self.memory:.4g}")
except:
pass
def mem_sub(self):
try:
val = safe_eval(self.expr_var.get())
self.memory -= val
self.mem_label.config(text=f"M: {self.memory:.4g}")
except:
pass
# 进制转换器 (新窗口)
def show_converter(self):
win = tk.Toplevel(self.root)
win.title("进制转换器")
win.geometry("400x300")
win.configure(bg=self.colors['bg'])
tk.Label(win, text="输入数字:", fg=self.colors['text'], bg=self.colors['bg']).pack(pady=5)
entry = tk.Entry(win, font=('Courier', 12), bg='#000', fg='#0f0')
entry.pack(pady=5)
def convert():
try:
val = float(entry.get())
int_part = int(val)
dec = val - int_part
res = f"Dec: {val}\nHex: {hex(int_part)}\nBin: {bin(int_part)}\nOct: {oct(int_part)}"
if dec != 0:
res += f"\nFloat: {val}"
result_label.config(text=res)
except:
result_label.config(text="无效数字")
btn = self.create_cool_button(win, "转换", convert, 'func')
btn.pack(pady=5)
result_label = tk.Label(win, text="", fg='#ffaa88', bg=self.colors['bg'], font=('Consolas', 10))
result_label.pack(pady=10)
# 单位换算器
def show_unit_converter(self):
win = tk.Toplevel(self.root)
win.title("单位换算器")
win.geometry("450x350")
win.configure(bg=self.colors['bg'])
# 长度换算表 (米基准)
units = {'米': 1, '千米': 1000, '厘米': 0.01, '毫米': 0.001, '英里': 1609.34, '英尺': 0.3048, '英寸': 0.0254}
tk.Label(win, text="数值:", fg=self.colors['text'], bg=self.colors['bg']).pack(pady=5)
val_entry = tk.Entry(win, font=('Courier', 12), bg='#000', fg='#0f0')
val_entry.pack()
frame1 = tk.Frame(win, bg=self.colors['bg'])
frame1.pack(pady=5)
tk.Label(frame1, text="从:", fg='#fff', bg=self.colors['bg']).pack(side=tk.LEFT)
from_unit = ttk.Combobox(frame1, values=list(units.keys()), width=8)
from_unit.pack(side=tk.LEFT, padx=5)
from_unit.set('米')
tk.Label(frame1, text="到:", fg='#fff', bg=self.colors['bg']).pack(side=tk.LEFT)
to_unit = ttk.Combobox(frame1, values=list(units.keys()), width=8)
to_unit.pack(side=tk.LEFT, padx=5)
to_unit.set('千米')
def convert_unit():
try:
val = float(val_entry.get())
from_u = from_unit.get()
to_u = to_unit.get()
meters = val * units[from_u]
result = meters / units[to_u]
res_label.config(text=f"{val} {from_u} = {result:.6f} {to_u}")
except:
res_label.config(text="转换错误")
btn = self.create_cool_button(win, "转换", convert_unit, 'func')
btn.pack(pady=10)
res_label = tk.Label(win, text="", fg='#88ffaa', bg=self.colors['bg'], font=('Consolas', 11))
res_label.pack(pady=10)
def bind_keys(self):
"""绑定键盘快捷键"""
self.root.bind('<Key>', self.key_handler)
def key_handler(self, event):
key = event.char
if key in '0123456789+-*/().%':
self.insert_text(key)
elif key == '\r': # 回车
self.calculate()
elif event.keysym == 'BackSpace':
self.backspace()
elif event.keysym == 'Escape':
self.clear_all()
# ==================== 程序入口 ====================
if __name__ == "__main__":
root = tk.Tk()
app = SuperCoolCalculator(root)
root.mainloop()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。