3

我正在尝试将一个函数绑定到我的 Tkinter 根目录,该根目录会在用户按下返回时做出反应。这是代码:

def returnPressed(event):
    print repr(event.widget)

master = Tk()

master.bind("<Return>", returnPressed)
myStringVar = StringVar(value="Foo")
myEntry = Entry(master, textvariable=myStringVar)
myEntry.grid()

master.mainloop()

这可行,但是现在我需要在函数中获取while的StringVar变量。EntryreturnPressed

我有小部件,但我无法获取变量对象。我知道如何获取变量内容,但我真的需要对象。

4

4 回答 4

2

要获取小部件的任何属性,请使用cget

print(event.widget.cget("textvariable"))

然而,在这个特定的实例中,由于一些实现细节,您得到的是 stringvar 的内部名称,而不是 stringvar 本身。所以,你必须找到另一种方法。

最简单的事情可能是将 stringvar 实例传递给被调用的函数。您可以使用 lambda 或 functools.partial 执行此操作。例如:

def returnPressed(event, v):
    ...
master.bind("<Return>",lambda event, v=myStringVar: returnPressed(event, v))
于 2013-01-31T17:45:20.923 回答
0

我通过使用一个外部对象来解决 tkinter 在这方面的糟糕设计,该对象包含对它使用的EntryStringVar它使用的文本变量的引用,以便于访问(atuple也可以工作):

class EntryWithText()
    def __init__(self):
        self.entry = None
        self.textvariable = StringVar() #or None


entryWithTexts = []
for i in range(10):
    entryWithTexts[i] = EntryWithText()
    entryWithTexts[i].entry = Entry(master, textvariable=entryWithTexts[i].textvariable, ...)
    entryWithTexts[i].textvariable.set("this is entry number " + str(i))

毫无疑问,如果你有 100k 个这样的条目,额外的间接级别会产生一些影响,但我在这里写的是小工具,所以不用担心。

于 2018-06-20T18:33:43.990 回答
0

以为我会继续说我发现了一种方法。

读取小部件的 'textvariable' 选项值会为您提供先前设置的变量的名称。使用此名称初始化 StringVar 实例将为您提供一个似乎链接到原始实例的新实例。没有值的初始化会保留当前值。我说“链接”是因为新实例和原始实例不是同一个对象(由它们的 id 验证),但是在新实例上设置值将更改小部件中对象中的值。请参阅 Variable._ init _ 的文档。

    name = event.widget['textvariable']
    var = StringVar(root, name=name)
于 2022-01-22T02:19:45.290 回答
-1

我知道这是一个老问题,但我认为我通过内部化控制变量找到了解决 tkinter 限制的方法。然后,您无需在创建小部件时声明单独的值:

class DynamicLabel(tkinter.Label):
    def __init__(self, master, *args, **kwargs):
        super().__init__(master=master, *args, **kwargs)
        self.master = master
        self.value=None
        for kwarg, value in kwargs.items():
            if kwarg == 'textvariable':
                if not isinstance(value, tkinter.StringVar):
                    raise ValueError('Textvariable must be StringVar')
                self.value = value
        if not self.value:
            self.value = tkinter.StringVar()
            self.config(textvariable=self.value)

    def set(self, txt):
        self.value.set(txt)

    def get(self):
        return self.value.get()

这样做是为控制变量创建一个代理self.value

然后我们将遍历所有的 kwargs,如果textvariable找到我们就self.value引用它。

如果在创建小部件时没有设置文本变量,我们只需创建自己的并将其分配给小部件self.config(textvariable=self.value)

剩下的就是创建 set 和 get 方法来访问控制变量。

textvariable我想通过忽略创建小部件时分配的任何内容并始终从头开始创建新小部件,可以进一步简化上述内容。

您甚至可以制作self.value一个能够直接与之交互的属性self.value

于 2021-06-13T10:12:33.650 回答