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

基于tkinter实现属性编辑器控件自适应窗口拉伸的问题

属性编辑器自适应布局实现方案

环境

  • Python 3.12
  • Windows 10

当前效果

当前效果

需求

窗口调整大小时,实现以下自适应拉伸效果:

  1. StringWidget的Entry控件拉伸至窗口末端
  2. FileWidget的Entry控件填充标签与按钮之间的剩余空间
  3. 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()

核心改动说明

  1. AttributeEditor:添加self.grid_columnconfigure(0, weight=1),让第0列拥有拉伸权重,确保整个编辑器区域随窗口宽度变化。
  2. StringWidget:给Entry的pack方法添加fill="x", expand=True,使Entry填充水平方向剩余空间。
  3. FileWidget:移除固定宽度设置,同时给Entry添加fill="x", expand=True,让Entry占据标签和按钮之间的所有可用空间。
  4. Point3DWidget:给三个Spinbox的pack方法都添加fill="x", expand=True,这样三个控件会自动均分标签右侧的剩余水平空间,随窗口同步拉伸。

内容的提问来源于stack exchange,提问作者Prashant

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:45:15