基于tkinter实现属性编辑器控件自适应窗口拉伸的问题
属性编辑器自适应布局实现方案
环境
- Python 3.12
- Windows 10
当前效果

需求
窗口调整大小时,实现以下自适应拉伸效果:
- StringWidget的Entry控件拉伸至窗口末端
- FileWidget的Entry控件填充标签与按钮之间的剩余空间
- Point3DWidget的三个Spinbox均分标签到窗口末端的空间并随窗口拉伸
参考效果

修改后代码
import tkinter as tk from tkinter import colorchooser from tkinter.filedialog import asksaveasfile from tkinter import ttk # Third party from tkscrolledframe import ScrolledFrame import os if os.name == 'nt': from ctypes import windll windll.shcore.SetProcessDpiAwareness(1) LABEL_WIDTH = 14 PADX = 5 PADY = 3 class StringWidget(tk.Frame): def __init__(self, parent, label:str, default=""): tk.Frame.__init__(self, parent) self.label = tk.Label(self, text=label, anchor="e", width=LABEL_WIDTH) self.entry = tk.Entry(self) self.entry.insert(0, default) self.label.pack(side="left", padx=PADX) # 让Entry填充水平剩余空间 self.entry.pack(side="left", padx=PADX, fill="x", expand=True) class FileWidget(tk.Frame): def __init__(self, parent, label:str, default=""): tk.Frame.__init__(self, parent) self.label = tk.Label(self, text=label, anchor="e", width=LABEL_WIDTH) self.entry = tk.Entry(self) self.entry.insert(0, default) self.btn = tk.Button(self, text="Browse") self.label.pack(side="left", padx=PADX) # Entry填充标签与按钮间的剩余空间 self.entry.pack(side="left", padx=PADX, fill="x", expand=True) self.btn.pack(side="left", padx=PADX) class Point3DWidget(tk.Frame): def __init__(self, parent, label:str, minv:int=0, maxv:int=10, default:int=0, incr:int=1, format="%.0f"): tk.Frame.__init__(self, parent) self.strv = tk.StringVar() self.strv.set(default) self.label = tk.Label(self, text=label, anchor='e', width=LABEL_WIDTH) self.spinbox1 = ttk.Spinbox(self, from_=minv, to=maxv, increment=incr, format=format, textvariable=self.strv, wrap=True) self.spinbox2 = ttk.Spinbox(self, from_=minv, to=maxv, increment=incr, format=format, textvariable=self.strv, wrap=True) self.spinbox3 = ttk.Spinbox(self, from_=minv, to=maxv, increment=incr, format=format, textvariable=self.strv, wrap=True) self.label.pack(side="left", padx=PADX) # 三个Spinbox均分剩余水平空间 self.spinbox1.pack(side="left", padx=PADX, fill="x", expand=True) self.spinbox2.pack(side="left", padx=PADX, fill="x", expand=True) self.spinbox3.pack(side="left", padx=PADX, fill="x", expand=True) class AttributeEditor(tk.Frame): def __init__(self, parent): tk.Frame.__init__(self, parent) self.label = tk.Label(self, text="Theme", font=('bold')) self.sw = StringWidget(self, "String Widget", "Inigo") self.fw = FileWidget(self, "File Widget", "Inigo") self.pw = Point3DWidget(self, "Point 3D Widget", 0, 10, 6) # 配置列权重,让列随窗口拉伸 self.grid_columnconfigure(0, weight=1) self.label.grid(row=0, column=0, sticky="w", padx=PADX, pady=PADY) self.sw.grid(row=1, column=0, sticky="ew", pady=PADY) self.fw.grid(row=2, column=0, sticky="ew", pady=PADY) self.pw.grid(row=3, column=0, sticky="ew", pady=PADY) separator = ttk.Separator(self, orient='horizontal') separator.grid(row=9, column=0, sticky="ew", pady=PADX, padx=PADY) if __name__ == "__main__": root = tk.Tk() root.title("Attribute Editor") root.geometry("380x360") # Create a ScrolledFrame widget sf = ScrolledFrame(root) sf.pack(side="top", expand=1, fill="both") # Bind the arrow keys and scroll wheel sf.bind_arrow_keys(root) sf.bind_scroll_wheel(root) # Create a frame within the ScrolledFrame inner_frame = sf.display_widget(AttributeEditor) root.mainloop()
核心改动说明
- AttributeEditor:添加
self.grid_columnconfigure(0, weight=1),让第0列拥有拉伸权重,确保整个编辑器区域随窗口宽度变化。 - StringWidget:给Entry的
pack方法添加fill="x", expand=True,使Entry填充水平方向剩余空间。 - FileWidget:移除固定宽度设置,同时给Entry添加
fill="x", expand=True,让Entry占据标签和按钮之间的所有可用空间。 - Point3DWidget:给三个Spinbox的
pack方法都添加fill="x", expand=True,这样三个控件会自动均分标签右侧的剩余水平空间,随窗口同步拉伸。
内容的提问来源于stack exchange,提问作者Prashant
相关产品推荐
相关产品推荐

