如何使用验证器函数中的窗口小部件名称?

时间:2017-09-18 02:02:40

标签: python tkinter widget

我找到了这段代码: Interactively validating Entry widget content in tkinter

import tkinter as tk  # python 3.x
# import Tkinter as tk # python 2.x

class Example(tk.Frame):

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        # valid percent substitutions (from the Tk entry man page)
        # note: you only have to register the ones you need; this
        # example registers them all for illustrative purposes
        #
        # %d = Type of action (1=insert, 0=delete, -1 for others)
        # %i = index of char string to be inserted/deleted, or -1
        # %P = value of the entry if the edit is allowed
        # %s = value of entry prior to editing
        # %S = the text string being inserted or deleted, if any
        # %v = the type of validation that is currently set
        # %V = the type of validation that triggered the callback
        #      (key, focusin, focusout, forced)
        # %W = the tk name of the widget

        vcmd = (self.register(self.onValidate),
                '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
        self.entry = tk.Entry(self, validate="key", validatecommand=vcmd)
        self.text = tk.Text(self, height=10, width=40)
        self.entry.pack(side="top", fill="x")
        self.text.pack(side="bottom", fill="both", expand=True)

    def onValidate(self, d, i, P, s, S, v, V, W):
        self.text.delete("1.0", "end")
        self.text.insert("end","OnValidate:\n")
        self.text.insert("end","d='%s'\n" % d)
        self.text.insert("end","i='%s'\n" % i)
        self.text.insert("end","P='%s'\n" % P)
        self.text.insert("end","s='%s'\n" % s)
        self.text.insert("end","S='%s'\n" % S)
        self.text.insert("end","v='%s'\n" % v)
        self.text.insert("end","V='%s'\n" % V)
        self.text.insert("end","W='%s'\n" % W)

        # Disallow anything but lowercase letters
        if S == S.lower():
            return True
        else:
            self.bell()
            return False

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()

我需要使用实例(%W),但它是一个字符串。我需要这样的东西:

import tkinter as tk  # python 3.x
# import Tkinter as tk # python 2.x

class Example(tk.Frame):

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        vcmd = (self.register(self.onValidate),
                '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
        self.entry = tk.Entry(self, validate="key", validatecommand=vcmd)
        self.text = tk.Text(self, height=10, width=40)
        self.entry.pack(side="top", fill="x")
        self.text.pack(side="bottom", fill="both", expand=True)

    def onValidate(self, d, i, P, s, S, v, V, W):
        print type(W) #This gives <string>
        W = instance(W) #Something to convert the string to an instance like int()
        W.get()
        W.insert('Some text',0)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()

我需要一种方法来修改附加了valitation函数的小部件,因为register方法只将小部件的路径或指针作为字符串。但我需要修改小部件。

我一直在考虑将所有小部件放在一个名为&#34; instance&#34;的列表中,然后为实例中的w创建一个&#34;&#34;并将所有小部件与验证器函数的%W进行比较,直到找到相同的小部件名称,然后修改列表中的对象。

有没有办法更轻松地做到这一点?谢谢你们!

1 个答案:

答案 0 :(得分:1)

验证功能不是为您在验证期间修改窗口小部件的内容而设计的。

来自canonical tcl/tk documentation

  

当您在validateCommand或invalidCommand中编辑条目窗口小部件时,validate选项也会将自身设置为none。此类版本将覆盖正在验证的版本。如果您希望在验证期间编辑条目小部件(例如将其设置为{})并且仍设置了验证选项,则应包含命令

话虽如此,如果需要,您可以使用可以通过任何小部件调用的方法nametowidget将小部件名称转换为小部件引用。

def onValidate(self, d, i, P, s, S, v, V, W):
    widget = self.nametowidget(W)
    ...