【问题标题】:How can I disable takefocus for a parent and all of its children?如何禁用父母及其所有孩子的焦点?
【发布时间】:2017-11-18 10:57:01
【问题描述】:

我可以为一个小部件写widget.configure(takefocus=False) 来实现我想要的。但是有没有一种方法可以轻松地禁用对父小部件及其所有子小部件的关注,而不是遍历每个子小部件并逐个禁用?

这是一个例子:

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


class BasicOperations(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        operations = "+-*/"
        self.buttons = list()
        for op in operations:
            self.buttons.append(tk.Button(self, text=op))
        #configure the geometry
        for i in range(len(self.buttons)):
            self.buttons[i].grid()


if __name__ == '__main__':
    root = tk.Tk()
    basic_ops = BasicOperations(root)
    basic_ops.pack()
    root.mainloop()

我尝试在__init__ 中调用self.configure(takefocus=False),但它并没有禁用它下面的按钮的焦点。

【问题讨论】:

  • 在设置command 和布局几何时为什么不用for button in self.buttons:
  • @DonalFellows 这就是我最初会做的,但想知道是否有更好的方法。

标签: python tkinter tcl tk


【解决方案1】:

焦点决定不是像那样递归地强制执行,因为包含小部件(通常是框架)即使它们包含的小部件确实获得焦点也不获得焦点是很正常的。但是,takefocus 属性不需要是静态的;它可以设置为返回布尔值的可调用对象,以便在任何时候做出焦点遍历决定时,可调用对象都会决定当前小部件是否应该具有焦点。这意味着您所要做的就是提供一个可调用函数,该可调用函数从感兴趣的组中通用的变量返回一个值。

你有一个方便的类,它提供了一个合理的范围,所以类实例的方法是一个完美的可调用对象。

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


class BasicOperations(tk.Frame):
    def _take_focus_handler(self):
        return self._group_focusable

    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self._group_focusable = True
        operations = "+-*/"
        self.buttons = list()
        for op in operations:
            self.buttons.append(tk.Button(self, text=op,
                                        takefocus=self._take_focus_handler))
        #configure the geometry
        for i in range(len(self.buttons)):
            self.buttons[i].grid()

    def set_group_focusable(self, value=True):
        self._group_focusable = value
        # Note that you might also want to defocus the widgets if the focus is
        # already in the group, but you didn't ask for that...


if __name__ == '__main__':
    root = tk.Tk()
    basic_ops = BasicOperations(root)
    basic_ops.pack()
    root.mainloop()

【讨论】:

  • 我更新了我的问题以提高可读性,并共同编辑了您的答案以更好地反映它。当一个按钮获得焦点时,您提供的代码似乎会引发错误,因为显然takefocus 使用一个位置参数调用它的引用。我会将这个替换方法定义修复为def _take_focus_handler(self, focused_widget_name=None):,但这是你的答案,所以我没有。
【解决方案2】:

您可以分两步解决:

  1. 为父小部件禁用takefocus
  2. 遍历该父小部件的children 并为每个小部件禁用takefocus

    for child in self.winfo_children():
        child.configure(takefocus=False)
    

【讨论】:

  • 这个迭代。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-09
  • 1970-01-01
  • 2015-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多