有谁知道是否已经有一个小部件/类来处理基于 tkinter/ttk 中的切换按钮(检查按钮)扩展/收缩框架?
这个问题源于我试图清理一个混乱的图形用户界面,该图形用户界面有很多按特定操作分类的选项。我想要一些类似的东西:
在谷歌上找到的例子
然而,不仅仅是文本,还允许按钮、条目、任何 tkinter 的小部件。如果这还不存在,是否可以/有用创建一个继承 tkinter Frame 的类:
import tkinter as tk
import ttk
class toggledFrame(tk.Frame):
def __init__(self):
self.show=tk.IntVar()
self.show.set(0)
self.toggleButton=tk.Checkbutton(self, command=self.toggle, variable=self.show)
self.toggleButton.pack()
self.subFrame=tk.Frame(self)
def toggle(self):
if bool(self.show.get()):
self.subFrame.pack()
else:
self.subFrame.forget()
注意:此代码未经测试,仅呈现概念
实际上,我对自己距离获得正常运行的代码如此之近感到惊讶。我决定进一步研究它,并开发一个简单的小类来完全执行我想要的操作(欢迎对代码提出评论和建议):
import tkinter as tk
from tkinter import ttk
class ToggledFrame(tk.Frame):
def __init__(self, parent, text="", *args, **options):
tk.Frame.__init__(self, parent, *args, **options)
self.show = tk.IntVar()
self.show.set(0)
self.title_frame = ttk.Frame(self)
self.title_frame.pack(fill="x", expand=1)
ttk.Label(self.title_frame, text=text).pack(side="left", fill="x", expand=1)
self.toggle_button = ttk.Checkbutton(self.title_frame, width=2, text='+', command=self.toggle,
variable=self.show, style='Toolbutton')
self.toggle_button.pack(side="left")
self.sub_frame = tk.Frame(self, relief="sunken", borderwidth=1)
def toggle(self):
if bool(self.show.get()):
self.sub_frame.pack(fill="x", expand=1)
self.toggle_button.configure(text='-')
else:
self.sub_frame.forget()
self.toggle_button.configure(text='+')
if __name__ == "__main__":
root = tk.Tk()
t = ToggledFrame(root, text='Rotate', relief="raised", borderwidth=1)
t.pack(fill="x", expand=1, pady=2, padx=2, anchor="n")
ttk.Label(t.sub_frame, text='Rotation [deg]:').pack(side="left", fill="x", expand=1)
ttk.Entry(t.sub_frame).pack(side="left")
t2 = ToggledFrame(root, text='Resize', relief="raised", borderwidth=1)
t2.pack(fill="x", expand=1, pady=2, padx=2, anchor="n")
for i in range(10):
ttk.Label(t2.sub_frame, text='Test' + str(i)).pack()
t3 = ToggledFrame(root, text='Fooo', relief="raised", borderwidth=1)
t3.pack(fill="x", expand=1, pady=2, padx=2, anchor="n")
for i in range(10):
ttk.Label(t3.sub_frame, text='Bar' + str(i)).pack()
root.mainloop()
此代码产生:
据我所知,Tkinter/ttk 不提供此类小部件。您可以使用 tkinter.ttk.Treeview
来模仿您的示例(展开/折叠label 列表)。
开发自己的小部件是完全可以接受的1,并且您的代码似乎是一个正确的开始。
与接受的答案基本相同,但此示例负责让子类接受关键字参数
fg
、font
和 bg
并做出一些不同的样式选择,同时展示如何使用它。
基本思想是对
tk.Frame
进行子类化,其中包含两个附加框架。
一,在此示例中名为 frame
,用于包含内容 self.label
和 self.button
。
这是必要的,以避免 tkinter 的包管理器按照我们不喜欢的顺序放置小部件。
第二,在此示例中,名为 self.extension
的框架将通过切换按钮进行打包和 解包。
root = tk.Tk()
class ModernExpandableFrame(tk.Frame):
def __init__(self, master, **kwargs):
bg = kwargs.pop('bg', None)
fg = kwargs.pop('fg', None)
tx = kwargs.pop('text', '')
ft = kwargs.pop('font', '10')
super().__init__(master, bg=bg, **kwargs)
frame = tk.Frame(self,relief=tk.SOLID, bd=1)
self.label = tk.Label(
frame, bg=bg, fg=fg, text=tx)
self.button = tk.Button(
frame, bg=bg, fg=fg, text='↲', relief=tk.FLAT,
font=ft, command=self.toggle)
frame.pack(side=tk.TOP,expand=True,fill=tk.BOTH)
self.label.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.button.pack(side=tk.RIGHT,fill=tk.Y)
self.extension = tk.Frame(self, bg=bg, **kwargs)
return
def toggle(self):
if self.extension not in self.pack_slaves():
self.extension.pack(side=tk.BOTTOM,expand=True,fill=tk.BOTH)
else:
self.extension.pack_forget()
pass
ex_frame = ModernExpandableFrame(root,
bg='grey', fg='white',
text='Super Frame')
ex_frame.pack(expand=True, fill=tk.BOTH)
extension = ex_frame.extension
for i in range (10):
tk.Button(extension, text=i, command=lambda i=i: print(i)).pack()
root.mainloop()