我遇到了tkinter trace方法的回调函数问题。我想有2个条目,每个条目的值取决于另一个条目的值。因此,如果我更改1的值,则更改另一个的值。这是一些简单的代码:
from tkinter import *
class main():
def __init__(self, master):
self.a = DoubleVar(value=2.0)
self.b = DoubleVar()
self.b.trace("w",self.calc_c)
self.c = DoubleVar()
self.c.trace("w",self.calc_b)
Entry(master,textvariable=self.b).grid(row=0,column=0)
Entry(master,textvariable=self.c).grid(row=0,column=1)
def calc_b(self,name,index,mode):
self.b.set(self.c.get()/self.a.get())
def calc_c(self,name,index,mode):
self.c.set(self.b.get()*self.a.get())
root = Tk()
prog = main(root)
root.mainloop()
程序实际上正在运行,返回正确的值,但也会产生错误:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib64/python3.3/tkinter/__init__.py", line 1475, in __call__
return self.func(*args)
File "/home/anze/foo.py", line 22, in calc_c
self.c.set(self.b.get()*self.a.get())
File "/usr/lib64/python3.3/tkinter/__init__.py", line 332, in get
return getdouble(self._tk.globalgetvar(self._name))
ValueError: could not convert string to float:
有人可以解释一下这个错误的含义吗?
谢谢!
答案 0 :(得分:0)
我相信您的问题是您将self.c绑定到Entry小部件:
Entry(master,textvariable=self.c).grid(row=0,column=1)
但是,textvariable应设置为Tkinter.StringVar
。如何创建一个新变量来保存Entry的字符串值,然后在calc方法中进行转换:
from tkinter import *
class main():
def __init__(self, master):
self.a = DoubleVar(value=2.0)
self.b = DoubleVar()
self.b.trace("w",self.calc_c)
self.c = DoubleVar()
self.c_str = StringVar()
self.c.trace("w",self.calc_b)
Entry(master,textvariable=self.b).grid(row=0,column=0)
Entry(master,textvariable=self.c_str).grid(row=0,column=1)
def calc_b(self,name,index,mode):
self.c.set(float(self.c_str.get()))
self.b.set(self.c.get()/self.a.get())
def calc_c(self,name,index,mode):
self.c.set(self.b.get()*self.a.get())
root = Tk()
prog = main(root)
root.mainloop()
请注意,您可能希望对其他条目执行相同的操作。
答案 1 :(得分:0)
我认为问题在于窗口小部件是一个条目,它以字符串作为输入,而您的值是DoubleVar,但您没有进行任何验证以防止用户输入无效值。
只要输入值是浮点数,您的代码就会起作用。在输入无效值后,在get()
和calc_c
中调用calc_b
时,tkinter会尝试将Entry中的字符串转换为float,失败并抛出ValueError异常。
您可以使用try-except块捕获异常。在try
块中,您放置了可能引发异常的代码。 except
块定义捕获异常时发生的情况。您还可以使用else
块来定义未捕获异常时发生的情况。
以下是calc_c的一个简单示例(没有else块),它恢复了以前的值(calc_b需要以类似的方式修改):
def calc_c(self,name,index,mode):
try:
self.c.set(self.b.get()*self.a.get())
except ValueError:
# here you can either complain to the user (message-box...)
# or just restore the last value using the other entry like so:
self.b.set(self.c.get()/self.a.get())
答案 2 :(得分:0)
我使用Tk.scale(... resolution=0.1, ...)
发生了类似的错误。
如果在同一个脚本中使用了matplotlib
,则缩放后的十进制数字会使用,
而不是.
来编写,并在getdouble()
中导致错误。
我找到了一种解决方法,将os(kubuntu14.04)的区域设置从德语更改为美国,.
为默认小数分隔符。
它不能令人满意的解决方案,但可能有助于找到问题。