【问题标题】:Is there a way to gray out (disable) a tkinter Frame?有没有办法使 tkinter Frame 变灰(禁用)?
【发布时间】:2014-09-16 13:01:24
【问题描述】:

我想在 tkinter 中创建一个带有两个 Frame 的 GUI,并让底部 Frame 变灰,直到发生某些事件。

下面是一些示例代码:

from tkinter import *
from tkinter import ttk

def enable():
    frame2.state(statespec='enabled') #Causes error

root = Tk()

#Creates top frame
frame1 = ttk.LabelFrame(root, padding=(10,10,10,10))
frame1.grid(column=0, row=0, padx=10, pady=10)

button2 = ttk.Button(frame1, text="This enables bottom frame", command=enable)
button2.pack()

#Creates bottom frame
frame2 = ttk.LabelFrame(root, padding=(10,10,10,10))
frame2.grid(column=0, row=1, padx=10, pady=10)
frame2.state(statespec='disabled') #Causes error

entry = ttk.Entry(frame2)
entry.pack()

button2 = ttk.Button(frame2, text="button")
button2.pack()

root.mainloop()

这是否可能无需单独灰显 frame2 的所有小部件?

我正在使用 Tkinter 8.5 和 Python 3.3。

【问题讨论】:

    标签: python tkinter frame state


    【解决方案1】:

    不确定它有多优雅,但我通过添加找到了解决方案

    for child in frame2.winfo_children():
        child.configure(state='disable')
    

    循环遍历并禁用 frame2 的每个子节点,并通过更改 enable() 来从本质上逆转这一点

    def enable(childList):
        for child in childList:
            child.configure(state='enable')
    

    此外,我删除了frame2.state(statespec='disabled'),因为这不能满足我的需要,而且还会引发错误。

    这是完整的代码:

    from tkinter import *
    from tkinter import ttk
    
    def enable(childList):
        for child in childList:
            child.configure(state='enable')
    
    root = Tk()
    
    #Creates top frame
    frame1 = ttk.LabelFrame(root, padding=(10,10,10,10))
    frame1.grid(column=0, row=0, padx=10, pady=10)
    
    button2 = ttk.Button(frame1, text="This enables bottom frame", 
                         command=lambda: enable(frame2.winfo_children()))
    button2.pack()
    
    #Creates bottom frame
    frame2 = ttk.LabelFrame(root, padding=(10,10,10,10))
    frame2.grid(column=0, row=1, padx=10, pady=10)
    
    entry = ttk.Entry(frame2)
    entry.pack()
    
    button2 = ttk.Button(frame2, text="button")
    button2.pack()
    
    for child in frame2.winfo_children():
        child.configure(state='disable')
    
    root.mainloop()
    

    【讨论】:

    • 如果您描述了您所做的事情,您的答案会更好。否则我们必须逐行阅读以寻找差异。
    • @BryanOakley 公平点。我的答案现已更新以使其更清晰。
    • 我必须将 state='enable' 更改为 state='normal' 才能使其正常工作。
    • @Big Sharpie 对此表示感谢。非常有帮助...只是一个问题...如果孩子也有孩子怎么办,是否有快速代码可以获取所有孩子?谢谢
    【解决方案2】:

    基于@big Sharpie 解决方案,这里有 2 个通用函数,可以禁用和启用小部件层次结构(框架“包含”)。 Frame 不支持状态设置器。

    def disableChildren(parent):
        for child in parent.winfo_children():
            wtype = child.winfo_class()
            if wtype not in ('Frame','Labelframe'):
                child.configure(state='disable')
            else:
                disableChildren(child)
    
    def enableChildren(parent):
        for child in parent.winfo_children():
            wtype = child.winfo_class()
            print (wtype)
            if wtype not in ('Frame','Labelframe'):
                child.configure(state='normal')
            else:
                enableChildren(child)
    

    【讨论】:

      【解决方案3】:

      我认为您可以简单地一次隐藏整个框架。 如果使用网格

       frame2.grid_forget()
      

      如果使用包

       frame2.pack_forget()
      

      在你的情况下,函数是

       def disable():
           frame2.pack_forget()
      

      再次启用

      def enable():
          frame2.pack()
      

      grid_forget()pack_forget() 可用于几乎所有 tkinter 小部件 这是一种简单的方法,可以减少代码的长度,我相信它可以工作

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-05
        • 1970-01-01
        • 2021-02-27
        相关资源
        最近更新 更多