0

tk.Toplevelインスタンス内のすべてのエントリ ボックスがいっぱいになったときにコマンドを実行したい。

現在、新しい入力が入力されるたびに、すべてがいっぱいかどうかを確認するようにしています。ただし、長い文字列が入力されるとすべての文字をチェックするため、これは非効率的になります (commandエントリが変更されるたびにエントリが実行されるため)。また、使用するエントリ ボックスが多数 (合計で約 30 個) あるため、これは恐ろしく非効率になります。

are_EntriesFull = lambda master: all(bool(widget.get()) for widget in filter(lambda s: isinstance(s, tk.Entry), findAllWidgets(master)))

_packingWidgets = (tk.Tk, tk.Toplevel, tk.Frame)

def findAllWidgets(master, widgetsFound = None):
    '''Returns all of the widgets in a packing instance'''
    if widgetsFound is None:
        widgetsFound = []
    subWidgets = master.grid_slaves()
    for widget in subWidgets:
        widgetsFound.append(widget)
        if isinstance(widget, _packingWidgets):
            widgetsFound.extend(findAllWidgets(widget, widgetsFound))
    return widgetsFound

class GetWord:

    '''Window to get input from the user and create an entry for the word'''
        def __init__(self, master, current, total):
            self.master, self.current, self.total, self.mainFrame = master, current, total, tk.Frame(master)
            self.master.title(STANDARD_TITLE)
            self.wordFrame, self.typeFrame, self.infoFrame, self.buttonFrame = tk.Frame(self.mainFrame), tk.Frame(self.mainFrame), tk.Frame(self.mainFrame), tk.Frame(self.mainFrame)
            self.word = tk.StringVar(self.wordFrame)
            self.wordLabel = tk.Label(self.wordFrame, text = "{}/{}) Word:".format(self.current, self.total), justify = tk.CENTER)
            self.activateButton = lambda: self.okButton.configure(state = tk.ACTIVE) if are_EntriesFull(self.master) else None
            self.wordEntry = tk.Entry(self.wordFrame, width = 50, justify = tk.CENTER, textvariable = self.word, command = self.activateButton)
                    # bunch of other code

基本的に、コマンドが行うべきことはボタンをアクティブにすることです (すべてのエントリが入力された場合にのみ使用したい)。別の方法として、ボタンが押されたときにエントリ ボックスがオンになっているかどうかを確認し (したがって、常にアクティブなままにしておく)、それらがいっぱいの場合にのみボタンのコマンドを実行することもできますが、いっぱいになったときにのみアクティブにしたいと思います。 . これを達成するためのより良い方法はありますか?ありがとう!

4

2 に答える 2

1

毎回findAllWidgets呼び出すのではなく、結果を保存してその結果を再利用します。findAllWidgets

#are_EntriesFull = lambda master: all(bool(widget.get()) for widget in filter(lambda s: isinstance(s, tk.Entry), findAllWidgets(master)))
are_EntriesFull = lambda entries: all(bool(widget.get()) for widget in entries) # <---

_packingWidgets = (tk.Tk, tk.Toplevel, tk.Frame)

def findAllWidgets(master, widgetsFound = None):
    '''Returns all of the widgets in a packing instance'''
    if widgetsFound is None:
        widgetsFound = []
    subWidgets = master.grid_slaves()
    for widget in subWidgets:
        widgetsFound.append(widget)
        if isinstance(widget, _packingWidgets):
            widgetsFound.extend(findAllWidgets(widget, widgetsFound))
    return widgetsFound

class GetWord:

    '''Window to get input from the user and create an entry for the word'''
        def __init__(self, master, current, total):
            self.master, self.current, self.total, self.mainFrame = master, current, total, tk.Frame(master)
            self.master.title(STANDARD_TITLE)
            self.wordFrame, self.typeFrame, self.infoFrame, self.buttonFrame = tk.Frame(self.mainFrame), tk.Frame(self.mainFrame), tk.Frame(self.mainFrame), tk.Frame(self.mainFrame)
            self.word = tk.StringVar(self.wordFrame)
            self.wordLabel = tk.Label(self.wordFrame, text = "{}/{}) Word:".format(self.current, self.total), justify = tk.CENTER)
            self.activateButton = lambda: self.okButton.configure(state = tk.ACTIVE if are_EntriesFull(all_entries) else tk.DISABLED) # <---
            self.wordEntry = tk.Entry(self.wordFrame, width = 50, justify = tk.CENTER, textvariable = self.word, command = self.activateButton)
                    # bunch of other code

            ...

            all_entries = findAllWidgets(self.master) # <---
于 2013-06-19T00:56:36.520 に答える