[英]tkinter.LabelFrame with Checkbutton labelwidget
在tkinter
,我想要一個類似於LabelFrame
的框架,但帶有一個Checkbutton
作為標簽。
閱讀LabelFrame 源代碼后,我看到了labelwidget
選項並嘗試
checkbutton = tk.Checkbutton(text=text)
checkbutton_frame = tk.LabelFrame(window, labelwidget=checkbutton)
它在視覺上工作,但Checkbutton
最終成為window
( window.winfo_children()
) 的子級。 或者:
checkbutton_frame = tk.LabelFrame(window)
checkbutton = tk.Checkbutton(checkbutton_frame, text="Hello, frame")
checkbutton_frame.configure(labelwidget=checkbutton)
使Checkbutton
成為Checkbutton
的子LabelFrame
。 LabelFrame
的默認內置Label
不會出現在winfo_children
。 因為我在添加所有小部件后遞歸地設置了padx
和pady
,所以讓Checkbutton
中的winfo_children
通過將Checkbutton
移出其錨定位置來破壞布局。 是否有一個好的,干凈的方式來代替一Checkbutton
的Label
在LabelFrame
維持一致的(即沒有任何)后代的關系? 歡迎使用其他解決方法的答案。
最小化復制
import tkinter as tk
def pack_configure_recursive(widget, **kwargs):
stack = list(widget.winfo_children())
while stack:
descendent = stack.pop()
try:
stack.extend(descendent.winfo_children())
except Exception:
pass
try:
descendent.pack_configure(**kwargs)
except Exception:
pass
class CheckbuttonFrame(tk.LabelFrame):
def __init__(self, master=None, **kwargs):
def pop_kwarg(name):
nonlocal kwargs
if name in kwargs:
result = kwargs[name]
del kwargs[name]
return result
else:
return None
text = pop_kwarg("text")
self.variable = pop_kwarg("variable")
self.command = pop_kwarg("command")
tk.LabelFrame.__init__(self, master, **kwargs)
self.configure(labelwidget=tk.Checkbutton(text=text, variable=self.variable, command=self.handler)) # Use this to make a child of the window
# self.configure(labelwidget=tk.Checkbutton(self, text=text, variable=self.variable, command=self.handler)) # Use this to make a child of the frame
def update_state(self):
if self.variable:
state = 'normal' if self.variable.get() else 'disable'
stack = list(self.winfo_children())
while stack:
descendent = stack.pop()
try:
stack.extend(descendent.winfo_children())
except Exception:
pass
try:
descendent.configure(state=state)
except tk.TclError:
pass
def handler(self):
self.update_state()
if self.command:
external_command = self.command
external_command()
window = tk.Tk()
option = tk.IntVar()
checkbutton_frame = CheckbuttonFrame(window, text="My option group", variable=option)
checkbutton_frame.pack()
tk.Label(checkbutton_frame, text="More widgets here").pack()
checkbutton_frame.update_state()
pack_configure_recursive(window, padx=2, pady=2) # This line break the layout
window.mainloop()
LabelFrame 的默認內置 Label 不會出現在 winfo_children 中
那是因為LabelFrame
的內置標簽不是小部件。
是否有一種不錯的、干凈的方法可以用 Checkbutton 替換 LabelFrame 中的 Label 以保持一致(即沒有任何)后代關系? 歡迎使用其他解決方法的答案。
不,那里沒有。 小部件必須是某些東西的后代,根本無法繞過它。 從邏輯上講,它可能應該是 labelframe 本身的后代。
您必須自動重新打包小部件的任何代碼都需要跳過此小部件。
您調用pack_configure
代碼可能應該忽略任何未由 pack 管理的小部件,您可以這樣做:
if descendent.winfo_manager() == "pack":
descendent.pack_configure(**kwargs)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.