2

我对 tkinter 跟踪方法的回调函数有问题。我想要 2 个条目,每个条目的值取决于另一个条目的值。所以如果我改变一个的值,另一个的值就会改变。这是一些执行此操作的简单代码:

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: 

有人可以解释这个错误的含义吗?

谢谢!

4

3 回答 3

0

我相信您的问题是您将 self.c 绑定到 Entry 小部件:

Entry(master,textvariable=self.c).grid(row=0,column=1)

但是, textvariable 应该设置为Tkinter.StringVar. 如何创建一个新变量来保存条目的字符串值,然后在您的 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()

请注意,您可能希望对另一个条目执行相同的操作。

于 2013-10-27T16:29:51.897 回答
0

我认为问题在于小部件是一个条目,它接受一个字符串作为输入,而您的值是一个 DoubleVar,但是您没有进行验证以防止用户输入无效值。

只要输入值是浮点数,您的代码就可以工作。当您调用并get()在输入无效值之后,tkinter 尝试将 Entry 中的字符串转换为浮点数,失败并抛出 ValueError 异常。calc_ccalc_b

您可以使用 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())
于 2013-10-27T17:20:35.983 回答
0

我使用Tk.scale(... resolution=0.1, ...). 当matplotlib在同一个脚本中使用时,比例尺的十进制数被写入,而不是,.并导致getdouble().

我通过将 os(kubuntu14.04) 的区域设置从德语更改为美国并使用.默认的十进制分隔符找到了一种解决方法。

它不能令人满意的解决方案,但可能有助于找到问题。

于 2015-04-07T08:40:48.970 回答