Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Tkinter回调函数导致ValueError_Python_Callback_Tkinter - Fatal编程技术网

Python Tkinter回调函数导致ValueError

Python Tkinter回调函数导致ValueError,python,callback,tkinter,Python,Callback,Tkinter,我对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.c

我对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: 
有人能解释一下这个错误的含义吗


谢谢大家!

我认为您的问题在于将self.c绑定到入口小部件:

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()

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

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

只要输入值是浮点值,代码就可以工作。输入无效值后,在
calc_c
calc_b
中调用
get()
时,tkinter尝试将条目中的字符串转换为浮点,失败并引发ValueError异常

您可以使用try-except块捕获异常。在
try
块中,放置可能引发异常的代码。
except
块定义捕获异常时发生的情况。您还可以有一个
else
块,用于定义在未捕获异常时发生的情况

下面是一个简单的calc_c示例(没有else块),用于恢复以前的值(calc_b需要以类似的方式进行修改):


使用
Tk.scale(…分辨率=0.1,…)
时,我遇到了类似的错误。 当同一脚本中使用了
matplotlib
时,scale中的十进制数是用
而不是
写入的,并导致
getdouble()
中出现错误

我找到了一个解决办法,将操作系统(kubuntu14.04)的区域设置从德语更改为US,并使用
作为默认的十进制分隔符


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

错误消息会准确地告诉您出了什么问题。您不明白“无法将字符串转换为浮点”是什么意思吗?或者您需要其他类型的帮助吗?我不明白哪个字符串正在转换为浮点。据我所知,所有变量都是浮点数,但显然不是这样,所以我很困惑……我同意,Entry小部件的textvariable应该是字符串。同样在这种情况下,我认为这应该起作用:
Entry(master,textvariable=str(self.b)).grid(row=0,column=0)Entry(master,textvariable=str(self.c)).grid(row=0,column=1)
。我还尝试了您的代码,但在更改第二个条目时,第一个条目没有得到更改。不是字符串,而是Tkinter.StringVar。因此,使用str()将不起作用。更改条目的值与ValueError实际上是一个单独的问题,我假设您只需要更新calc_c,使其行为与calc类似_b@user2923638你过得怎么样?如果这个答案对你有帮助,请点击复选标记。但是我得到这个错误,即使输入是一个有效的数字,而不是一些无效的字符串。在这种情况下,我不应该得到错误,是吗?你是否选择了整数并试图在上面键入?我刚试过,得到的信息和你一样。您无法在消息中看到该字符串,因为它是空字符串。(对于这一点,我作为示例发布的代码将防止它崩溃,但它不会给出正确的行为。)我的意思是:当您键入旧的数字时,实际发生的情况是输入框先清空(因此它包含一个空字符串),然后用您键入的字符替换其内容。但它永远不会到达那个点,因为只要输入框为空,异常就会立即生效。
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())