You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求为Python Tkinter计算器添加进制转换按钮及功能

Tkinter科学计算器进制转换功能实现方案

实现说明

  • 在计算器顶部新增DEC、BIN、OCT、HEX四个进制选择按钮,点击时向显示框插入对应标识
  • 操作流程:点击源进制按钮→输入对应进制的合法数字→点击目标进制按钮→按=完成转换
  • 输入验证:自动检查数字是否符合源进制规则,不符合则弹出错误提示
  • 兼容原有计算功能:未输入进制标识时,保留原科学计算器的运算逻辑

修改后的完整代码

from tkinter import *
from tkinter import filedialog
import tkinter.messagebox
import math

root = Tk()
root.geometry("650x450+300+300")  # 调整窗口高度容纳新按钮行
root.title("Scientific Calculator")
switch = None

# 进制标识插入函数
def insert_base(base):
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, base)

# 验证数字是否符合对应进制规则
def validate_number(num_str, base):
    try:
        if base == "BIN":
            int(num_str, 2)
        elif base == "OCT":
            int(num_str, 8)
        elif base == "DEC":
            int(num_str, 10)
        elif base == "HEX":
            int(num_str, 16)
        return True
    except ValueError:
        return False

# 进制转换逻辑
def convert_base(input_str):
    # 提取源进制、数字、目标进制
    bases = ["BIN", "OCT", "DEC", "HEX"]
    base_indices = []
    for base in bases:
        idx = input_str.find(base)
        if idx != -1:
            base_indices.append((idx, base))
    # 确保有且只有两个进制标识
    if len(base_indices) != 2:
        return None
    # 排序,第一个是源进制,第二个是目标进制
    base_indices.sort()
    (src_idx, src_base), (dest_idx, dest_base) = base_indices
    num_str = input_str[src_idx+len(src_base):dest_idx]
    if not num_str:
        return None
    # 验证数字合法性
    if not validate_number(num_str, src_base):
        return False
    # 转换为十进制,再转目标进制
    decimal_num = int(num_str, {"BIN":2, "OCT":8, "DEC":10, "HEX":16}[src_base])
    if dest_base == "BIN":
        return bin(decimal_num)[2:]  # 去掉前缀0b
    elif dest_base == "OCT":
        return oct(decimal_num)[2:]  # 去掉前缀0o
    elif dest_base == "DEC":
        return str(decimal_num)
    elif dest_base == "HEX":
        return hex(decimal_num)[2:].upper()  # 大写输出

# 数字按钮逻辑
def btn1_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, '1')
def btn2_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, '2')
def btn3_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, '3')
def btn4_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, '4')
def btn5_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, '5')
def btn6_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, '6')
def btn7_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, '7')
def btn8_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, '8')
def btn9_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, '9')
def btn0_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, '0')

# 十六进制字母按钮逻辑
def btnA_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, 'A')
def btnB_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, 'B')
def btnC_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, 'C')
def btnD_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, 'D')
def btnE_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, 'E')
def btnF_clicked():
    if disp.get() == '0':
        disp.delete(0, END)
    pos = len(disp.get())
    disp.insert(pos, 'F')

# 运算按钮逻辑
def btnp_clicked():
    pos = len(disp.get())
    disp.insert(pos, '+')
def btnm_clicked():
    pos = len(disp.get())
    disp.insert(pos, '-')
def btnml_clicked():
    pos = len(disp.get())
    disp.insert(pos, '*')
def btnd_clicked():
    pos = len(disp.get())
    disp.insert(pos, '/')    
def bl_clicked():
    pos = len(disp.get())
    disp.insert(pos, '(')
def br_clicked():
    pos = len(disp.get())
    disp.insert(pos, ')')
def sqr_clicked():
    try:
        ans = float(disp.get())
        ans = math.sqrt(ans)
        disp.delete(0, END)
        disp.insert(0, str(ans))
    except Exception:
        tkinter.messagebox.showerror("Value Error", "Check your values and operators")
def pow_clicked():
    pos = len(disp.get())
    disp.insert(pos, '**')
def mod_clicked():
    pos = len(disp.get())
    disp.insert(pos, '%')
def dot_clicked():
    pos = len(disp.get())
    disp.insert(pos, '.')
def btneq_clicked():
    try:
        input_str = disp.get().strip()
        # 先检查是否是进制转换格式
        bases = ["BIN", "OCT", "DEC", "HEX"]
        has_bases = any(base in input_str for base in bases)
        if has_bases:
            result = convert_base(input_str)
            if result is None:
                tkinter.messagebox.showerror("格式错误", "请按照【源进制+数字+目标进制】格式输入")
            elif result is False:
                tkinter.messagebox.showerror("输入错误", "数字不符合源进制规范")
            else:
                disp.delete(0, END)
                disp.insert(0, result)
        else:
            # 保留原有计算逻辑
            ans = eval(input_str)
            disp.delete(0, END)
            disp.insert(0, ans)
    except:
        tkinter.messagebox.showerror("Value Error", "Check your values and operators")

# 删除按钮逻辑
def del_clicked():
    pos = len(disp.get())
    display = str(disp.get())
    if display == '':
        disp.insert(0, '0')
    elif display == ' ':
        disp.insert(0, '0')
    elif display == '0':
        pass
    else:
        disp.delete(0, END)
        disp.insert(0, display[0:pos-1])
def btnc_clicked(*args):
    disp.delete(0, END)
    disp.insert(0, '0')

# 文件读取逻辑
def dat_clicked():
    file_path = filedialog.askopenfilename(filetypes=[('Text Files', '*.txt')])
    
    if file_path:
        with open(file_path, 'r') as file:
            content = file.read().replace('\n', '')
            disp.delete(0, END)
            pos = len(disp.get())
            disp.insert(pos, content)


data = StringVar()
disp = Entry(root, font="Verdana 20", fg="black", bg="mistyrose", bd=4, justify=RIGHT, insertbackground="#abbab1", cursor="arrow")
disp.pack(expand=TRUE, fill=BOTH)

# 新增进制按钮行
btnrow0 = Frame(root, bg="#000000")
btnrow0.pack(expand=TRUE, fill=BOTH)
dec_btn = Button(btnrow0, text="DEC", font="Segoe 18", relief=GROOVE, bd=0, command=lambda: insert_base("DEC"), fg="white", bg="#333333")
dec_btn.pack(side=LEFT, expand=TRUE, fill=BOTH)
bin_btn = Button(btnrow0, text="BIN", font="Segoe 18", relief=GROOVE, bd=0, command=lambda: insert_base("BIN"), fg="white", bg="#333333")
bin_btn.pack(side=LEFT, expand=TRUE, fill=BOTH)
oct_btn = Button(btnrow0, text="OCT", font="Segoe 18", relief=GROOVE, bd=0, command=lambda: insert_base("OCT"), fg="white", bg="#333333")
oct_btn.pack(side=LEFT, expand=TRUE, fill=BOTH)
hex_btn = Button(btnrow0, text="HEX", font="Segoe 18", relief=GROOVE, bd=0, command=lambda: insert_base("HEX"), fg="white", bg="#333333")
hex_btn.pack(side=LEFT, expand=TRUE, fill=BOTH)

# 原数字运算按钮行1
btnrow1 = Frame(root, bg="#000000")
btnrow1.pack(expand=TRUE, fill=BOTH)
mod_btn = Button(btnrow1, text="%", font="Segoe 21", relief=GROOVE, bd=0, command=mod_clicked, fg="white", bg="#333333")
mod_btn.pack(side=LEFT, expand=TRUE, fill=BOTH)
btn1 = Button(btnrow1, text="1", font="Segoe 23", relief=GROOVE, bd=0, command=btn1_clicked, fg="white", bg="#333333")
btn1.pack(side=LEFT, expand=TRUE, fill=BOTH)
btn2 = Button(btnrow1, text="2", font="Segoe 23", relief=GROOVE, bd=0, command=btn2_clicked, fg="white", bg="#333333")
btn2.pack(side=LEFT, expand=TRUE, fill=BOTH)
btn3 = Button(btnrow1, text="3", font="Segoe 23", relief=GROOVE, bd=0, command=btn3_clicked, fg="white", bg="#333333")
btn3.pack(side=LEFT, expand=TRUE, fill=BOTH)
btnp = Button(btnrow1, text="+", font="Segoe 23", relief=GROOVE, bd=0, command=btnp_clicked, fg="white", bg="#333333")
btnp.pack(side=LEFT, expand=TRUE, fill=BOTH)

# 新增十六进制字母按钮行
btnrow1_5 = Frame(root, bg="#000000")
btnrow1_5.pack(expand=TRUE, fill=BOTH)
btnA = Button(btnrow1_5, text="A", font="Segoe 23", relief=GROOVE, bd=0, command=btnA_clicked, fg="white", bg="#333333")
btnA.pack(side=LEFT, expand=TRUE, fill=BOTH)
btnB = Button(btnrow1_5, text="B", font="Segoe 23", relief=GROOVE, bd=0, command=btnB_clicked, fg="white", bg="#333333")
btnB.pack(side=LEFT, expand=TRUE, fill=BOTH)
btnC = Button(btnrow1_5, text="C", font="Segoe 23", relief=GROOVE, bd=0, command=btnC_clicked, fg="white", bg="#333333")
btnC.pack(side=LEFT, expand=TRUE, fill=BOTH)
btnD = Button(btnrow1_5, text="D", font="Segoe 23", relief=GROOVE, bd=0, command=btnD_clicked, fg="white", bg="#333333")
btnD.pack(side=LEFT, expand=TRUE, fill=BOTH)
btnE = Button(btnrow1_5, text="E", font="Segoe 23", relief=GROOVE, bd=0, command=btnE_clicked, fg="white", bg="#333333")
btnE.pack(side=LEFT, expand=TRUE, fill=BOTH)
btnF = Button(btnrow1_5, text="F", font="Segoe 23", relief=GROOVE, bd=0, command=btnF_clicked, fg="white", bg="#333333")
btnF.pack(side=LEFT, expand=TRUE, fill=BOTH)

# 原数字运算按钮行2
btnrow2 = Frame(root)
btnrow2.pack(expand=TRUE, fill=BOTH)
bl_btn = Button(btnrow2, text=" ( ", font="Segoe 21", relief=GROOVE, bd=0, command=bl_clicked, fg="white", bg="#333333")
bl_btn.pack(side=LEFT, expand=TRUE, fill=BOTH)
br_btn = Button(btnrow2, text=" ) ", font="Segoe 21", relief=GROOVE, bd=0, command=br_clicked, fg="white", bg="#333333")
br_btn.pack(side=LEFT, expand=TRUE, fill=BOTH)
btn4 = Button(btnrow2, text="4", font="Segoe 23", relief=GROOVE, bd=0, command=btn4_clicked, fg="white", bg="#333333")
btn4.pack(side=LEFT, expand=TRUE, fill=BOTH)
btn5 = Button(btnrow2, text="5", font="Segoe 23", relief=GROOVE, bd=0, command=btn5_clicked, fg="white", bg="#333333")
btn5.pack(side=LEFT, expand=TRUE, fill=BOTH)
btn6 = Button(btnrow2, text="6", font="Segoe 23", relief=GROOVE, bd=0, command=btn6_clicked, fg="white", bg="#333333")
btn6.pack(side=LEFT, expand=TRUE, fill=BOTH)
btnm = Button(btnrow2, text="-", font="Segoe 23", relief=GROOVE, bd=0, command=btnm_clicked, fg="white", bg="#333333")
btnm.pack(side=LEFT, expand=TRUE, fill=BOTH)

# 原数字运算按钮行3
btnrow3 = Frame(root)
btnrow3.pack(expand=TRUE, fill=BOTH)
sqr_btn = Button(btnrow3, text=" √x ", font="Segoe 18", relief=GROOVE, bd=0, command=sqr_clicked, fg="white", bg="#333333")
sqr_btn.pack(side=LEFT, expand=TRUE, fill=BOTH)
pow_btn = Button(btnrow3, text="x^y", font="Segoe 17", relief=GROOVE, bd=0, command=pow_clicked, fg="white", bg="#333333")
pow_btn.pack(side=LEFT, expand=TRUE, fill=BOTH)
btn7 = Button(btnrow3, text="7", font="Segoe 23", relief=GROOVE, bd=0, command=btn7_clicked, fg="white", bg="#333333")
btn7.pack
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 13:10:06