如何使用Tkinter将计算器代码改造为多标签页结构?
Tkinter真位置计算器标签页修复方案
你的代码对ttk.Notebook的用法完全错误——把每个单独的输入框/结果框都做成了标签页,所有标签都叫Tab-0,最后还把所有框架直接pack到主窗口,肯定达不到“每个计算器功能对应独立标签页”的效果。
问题点总结
- 错误将每个小控件框架(如
nom_x_frame、act_y_frame)添加为Notebook标签页,导致每个标签只有一个输入项 - 所有标签页名称重复为
Tab-0,无法区分功能 - 冗余创建
tab_control2但未使用 - 单独pack所有小框架,破坏了Notebook的标签页结构
修复后的代码
import tkinter as tk from tkinter import ttk import math as mt class truepositioncal: def __init__(self): # 创建主窗口 self.main_window = tk.Tk() self.main_window.title('True Position Calculator') self.main_window.geometry('400x400') # 放大窗口适配布局 # 只保留一个Notebook控件 self.tab_control = ttk.Notebook(self.main_window) # -------------------------- 创建功能标签页框架 -------------------------- # 1. 基础位置参数标签页 self.position_params_frame = ttk.Frame(self.tab_control) # 2. 尺寸公差参数标签页 self.tolerance_params_frame = ttk.Frame(self.tab_control) # 3. 结果展示标签页 self.results_frame = ttk.Frame(self.tab_control) # 添加标签页到Notebook,设置清晰的标签名 self.tab_control.add(self.position_params_frame, text='位置参数') self.tab_control.add(self.tolerance_params_frame, text='尺寸公差') self.tab_control.add(self.results_frame, text='计算结果') # 把Notebook放到主窗口 self.tab_control.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) # -------------------------- 填充【位置参数】标签页内容 -------------------------- # 最大位置偏差 self.maxtrueposition_frame = tk.Frame(self.position_params_frame) self.promptlabelmaxpos = tk.Label(self.maxtrueposition_frame, text='最大位置偏差:') self.maxposdev = tk.Entry(self.maxtrueposition_frame, width=10) self.promptlabelmaxpos.pack(side='left', padx=5) self.maxposdev.pack(side='left') self.maxtrueposition_frame.pack(pady=5, fill='x') # 标称X值 self.nom_x_frame = tk.Frame(self.position_params_frame) self.labeldrawingpara_x = tk.Label(self.nom_x_frame, text='标称X值:') self.nominal_x = tk.Entry(self.nom_x_frame, width=10) self.labeldrawingpara_x.pack(side='left', padx=5) self.nominal_x.pack(side='left') self.nom_x_frame.pack(pady=5, fill='x') # 标称Y值 self.nom_y_frame = tk.Frame(self.position_params_frame) self.labeldrawingpara_y = tk.Label(self.nom_y_frame, text='标称Y值:') self.nominal_y = tk.Entry(self.nom_y_frame, width=10) self.labeldrawingpara_y.pack(side='left', padx=5) self.nominal_y.pack(side='left') self.nom_y_frame.pack(pady=5, fill='x') # 实际X值 self.act_x_frame = tk.Frame(self.position_params_frame) self.labelact_x = tk.Label(self.act_x_frame, text='实际X值:') self.act_x = tk.Entry(self.act_x_frame, width=10) self.labelact_x.pack(side='left', padx=5) self.act_x.pack(side='left') self.act_x_frame.pack(pady=5, fill='x') # 实际Y值 self.act_y_frame = tk.Frame(self.position_params_frame) self.labelact_y = tk.Label(self.act_y_frame, text='实际Y值:') self.act_y = tk.Entry(self.act_y_frame, width=10) self.labelact_y.pack(side='left', padx=5) self.act_y.pack(side='left') self.act_y_frame.pack(pady=5, fill='x') # -------------------------- 填充【尺寸公差】标签页内容 -------------------------- # 标称直径 self.nom_dia_frame = tk.Frame(self.tolerance_params_frame) self.labelnomdia = tk.Label(self.nom_dia_frame, text='标称直径:') self.nom_dia = tk.Entry(self.nom_dia_frame, width=10) self.labelnomdia.pack(side='left', padx=5) self.nom_dia.pack(side='left') self.nom_dia_frame.pack(pady=5, fill='x') # 正公差 self.tol_pos_frame = tk.Frame(self.tolerance_params_frame) self.labeltolpos = tk.Label(self.tol_pos_frame, text='正公差(+):') self.tol_pos = tk.Entry(self.tol_pos_frame, width=10) self.labeltolpos.pack(side='left', padx=5) self.tol_pos.pack(side='left') self.tol_pos_frame.pack(pady=5, fill='x') # 负公差 self.tol_neg_frame = tk.Frame(self.tolerance_params_frame) self.labeltolneg = tk.Label(self.tol_neg_frame, text='负公差(-):') self.tol_neg = tk.Entry(self.tol_neg_frame, width=10) self.labeltolneg.pack(side='left', padx=5) self.tol_neg.pack(side='left') self.tol_neg_frame.pack(pady=5, fill='x') # 实际直径 self.act_dia_frame = tk.Frame(self.tolerance_params_frame) self.labelactdia = tk.Label(self.act_dia_frame, text='实际直径:') self.act_dia = tk.Entry(self.act_dia_frame, width=10) self.labelactdia.pack(side='left', padx=5) self.act_dia.pack(side='left') self.act_dia_frame.pack(pady=5, fill='x') # 计算按钮 self.calculate_frame = tk.Frame(self.tolerance_params_frame) self.calc_button = tk.Button(self.calculate_frame, text='计算', command=self.caltruepos) self.calc_button.pack(pady=10) self.calculate_frame.pack(pady=5) # -------------------------- 填充【计算结果】标签页内容 -------------------------- # 真位置结果 self.result_frame = tk.Frame(self.results_frame) self.result_label = tk.Label(self.result_frame, text='实际位置结果:') self.rs = tk.StringVar() self.rs_label = tk.Label(self.result_frame, textvariable=self.rs, width=10, relief='solid') self.result_label.pack(side='left', padx=5) self.rs_label.pack(side='left', padx=5) self.result_frame.pack(pady=10, fill='x') # MMC结果 self.mmc_frame = tk.Frame(self.results_frame) self.mmc_result_label = tk.Label(self.mmc_frame, text='MMC允许位置公差:') self.mmc = tk.StringVar() self.mmc_label = tk.Label(self.mmc_frame, textvariable=self.mmc, width=10, relief='solid') self.mmc_result_label.pack(side='left', padx=5) self.mmc_label.pack(side='left', padx=5) self.mmc_frame.pack(pady=10, fill='x') # LMC结果 self.lmc_frame = tk.Frame(self.results_frame) self.lmc_result_label = tk.Label(self.lmc_frame, text='LMC允许位置公差:') self.lmc = tk.StringVar() self.lmc_label = tk.Label(self.lmc_frame, textvariable=self.lmc, width=10, relief='solid') self.lmc_result_label.pack(side='left', padx=5) self.lmc_label.pack(side='left', padx=5) self.lmc_frame.pack(pady=10, fill='x') tk.mainloop() def caltruepos(self): try: # 读取输入并转换为浮点数 maxtrueposition = float(self.maxposdev.get()) nom_x_a = float(self.nominal_x.get()) nom_y_a = float(self.nominal_y.get()) act_x_a = float(self.act_x.get()) act_y_a = float(self.act_y.get()) nom_dia_a = float(self.nom_dia.get()) tol_pos_a = float(self.tol_pos.get()) tol_neg_a = float(self.tol_neg.get()) act_dia_a = float(self.act_dia.get()) # 计算真位置 x_diff = nom_x_a - act_x_a y_diff = nom_y_a - act_y_a square_root = mt.sqrt(x_diff**2 + y_diff**2) true_pos_value = 2 * square_root # 计算MMC和LMC允许公差 mmc_allowed = act_dia_a - (nom_dia_a - tol_neg_a) + maxtrueposition lmc_allowed = (nom_dia_a + tol_pos_a) - act_dia_a + maxtrueposition # 设置结果背景色 self.rs_label.config(bg='green' if true_pos_value <= maxtrueposition else 'red') self.mmc_label.config(bg='green' if true_pos_value <= mmc_allowed else 'red') self.lmc_label.config(bg='green' if true_pos_value <= lmc_allowed else 'red') # 格式化结果为3位小数 self.rs.set(f'{true_pos_value:.3f}') self.mmc.set(f'{mmc_allowed:.3f}') self.lmc.set(f'{lmc_allowed:.3f}') except ValueError: # 处理输入非数字的情况 self.rs.set('输入错误') self.mmc.set('输入错误') self.lmc.set('输入错误') self.rs_label.config(bg='yellow') self.mmc_label.config(bg='yellow') self.lmc_label.config(bg='yellow') trueposcal_a = truepositioncal()
关键修改说明
- 按功能分组标签页:创建三个核心标签页——位置参数、尺寸公差、计算结果,每个标签页包含一组相关控件
- 修正Notebook用法:每个标签页对应一个主框架,小框架嵌套在主框架内,而非直接作为标签页
- 优化布局:添加
padx、pady和fill='x'让控件布局更美观,调整窗口大小适配内容 - 增加错误处理:捕获输入非数字的情况,避免程序崩溃
- 移除冗余代码:删除未使用的
tab_control2,去掉单独pack小框架的错误代码
内容的提问来源于stack exchange,提问作者noel
相关产品推荐
相关产品推荐

