python-3.x - 使用 ttk 小部件时,tkinter 函数会重复两次
问题描述
当我简单地使用tkinter
's 小部件时,该程序按预期工作。当我使用ttk
's 小部件时,程序会重复两次。我几乎尝试了我所知道的一切来解决这个问题,我相信这*args
与它有关。有什么办法可以防止我function
跑两次?
from tkinter import *
from tkinter import ttk
root = Tk()
first = StringVar(root)
second = StringVar(root)
Ore = {'Options': [''], 'Yes': ['One'], 'No': ['Two']}
entry1 = ttk.OptionMenu(root, first, *Ore.keys())
entry2 = ttk.OptionMenu(root, second, '')
entry1.pack()
entry2.pack()
def _up_options(*args):
print('update_options')
ores = Ore[first.get()]
second.set(ores[0])
menu = entry2['menu']
menu.delete(0, 'end')
for line in ores:
print('for')
menu.add_command(label=line, command=lambda choice=line: second.set(choice))
first.trace('w', _up_options)
root.mainloop()
PS,我把*args
我的功能投入工作。如果有人能解释一下,我将不胜感激
解决方案
我想我想通了。问题是该变量实际上由 ttk OptionMenu 设置了两次。
看看 tkinter OptionMenu 中的这段代码:
for v in values:
menu.add_command(label=v, command=_setit(variable, v, callback))
这会为每个值添加一个带有_setit
命令的菜单按钮。当_setit
被调用时,它设置变量和另一个回调(如果提供):
def __call__(self, *args):
self.__var.set(self.__value)
if self.__callback:
self.__callback(self.__value, *args)
现在看一下来自 ttk OptionMenu 的这段代码:
for val in values:
menu.add_radiobutton(label=val,
command=tkinter._setit(self._variable, val, self._callback),
variable=self._variable)
而不是 acommand
这将 a 添加radiobutton
到菜单中。所有单选按钮都通过将它们链接到同一个变量来“分组”。因为单选按钮有一个变量,所以当单击其中一个时,该变量被设置为按钮的值。在此旁边,添加了与 tkinter OptionMenu 中相同的命令。如前所述,这会设置变量,然后触发另一个提供的命令。如您所见,现在变量更新了两次,一次是因为它链接到单选按钮,另一次是因为它是在_setit
函数中设置的。因为您跟踪变量的变化并且变量被设置了两次,所以您的代码也运行了两次。
因为该变量在 ttk 代码中设置了两次,所以我想您对此无能为力。如果您没有从代码的任何其他部分更改变量,而不是从 OptionMenu,您可以选择不跟踪变量,而是将您的函数添加command
到 OptionMenu:
entry1 = ttk.OptionMenu(root, first, *Ore.keys(), command=_up_options)
PS 这是在此错误报告之后的此提交中引入的。
我猜在添加命令时应该将其更改为 just 。variable=self._variable
command=self._callback
推荐阅读
- firebase - 使用交换机 Flutter 实时数据库
- reactjs - React - 如何使用已解决的承诺中的数据设置状态
- spring - 如何清理@restcontroller 中的请求对象
- python - 从 html 获取标题(解析)
- amazon-web-services - 在 AWS 上分发自定义 Windows AMI
- python-3.x - Keras 'set_session' 不适用于 Tensorflow 2.0
- java - 在Matlab图中设置java swing组件可见性时,一个矩形仍然存在
- c++ - 落沙模拟碰撞检测C++和SFML
- compiler-construction - 为什么我们需要 ABI 和调用约定
- javascript - 如何在nodejs中将字符串转换为Uint8Array类型