python-3.x - tkinter.LabelFrame 与 Checkbutton labelwidget
问题描述
在tkinter
中,我想要一个类似于 的框架LabelFrame
,但带有 aCheckbutton
作为标签。
阅读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
_ LabelFrame
默认的,内置的Label
不会LabelFrame
出现在winfo_children
. 因为我在添加所有小部件后设置padx
并pady
递归,所以通过将Checkbutton
in移出其锚定位置来winfo_children
破坏布局。Checkbutton
有没有一种很好的、干净的方法来代替保持一致(即没有任何)后代关系Checkbutton
的Label
in ?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 的默认内置标签不会出现在 winfo_children 中
那是因为 的内置标签LabelFrame
不是小部件。
有没有一种很好、干净的方法来用一个 Checkbutton 代替 LabelFrame 中保持一致(即没有任何)后代关系的标签?欢迎提供其他解决方法的答案。
不,那里没有。小部件必须是某物的后代,根本无法绕过它。从逻辑上讲,它可能应该是 labelframe 本身的后代。
您必须自动重新打包小部件的任何代码都需要跳过此小部件。
您要调用的代码pack_configure
可能应该忽略任何不由 pack 管理的小部件,您可以这样做:
if descendent.winfo_manager() == "pack":
descendent.pack_configure(**kwargs)
推荐阅读
- typescript - 从多重签名函数中选择一个特定的签名
- python-3.x - 在写入csv时仅终止每行的一列
- vb.net - 如何为我的项目(VB.Net)中的所有水晶报表设置全局连接字符串
- r - How do I read data with special characters (e.g. "¼") from SQL
- api - 如何使用 Telethon 在电报中管理给不同用户的消息?
- javascript - 递归:返回与布尔退出
- javascript - 如何从一个屏幕获取数据到另一个屏幕(当前使用 Stack Navigator)
- python - PackagesNotFoundError:以下软件包 pykg-config 在当前频道中不可用:
- python - Python 使用 time.sleep
- c++ - 重新声明纯虚函数