为什么Tkinter.StringVar()。get()试图将它自己的值转换为整数?

时间:2014-10-22 14:12:11

标签: python tkinter

所以我有一个滑块在更改时更新条目,并且该条目在更改时更新滑块。基本上它们都代表相同的值,但有两种不同的输入方法。相关方法看起来像这样(删节):

class MyWindow(Frame):

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack(fill=BOTH, expand=1)
        self.makeWidgets()

    def makeWidgets(self):

        #controls to set the radius of a circle
        #slider
        self.radSlider = Scale(self, command=self.updateEntry)
        self.radSlider.pack()

        #entry
        self.radVar = StringVar()
        vcmd = (self.master.register(self.validateInt),
            '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
        self.radEntry = Entry(self, 
                              validate = 'key', 
                              validatecommand = vcmd, 
                              textvariable=self.radVar)
        self.radEntry.pack()
        self.radVar.trace("w", self.updateSlide)

    def updateEntry(self, *event):
        rad = event[0]#first element of event is value of slider, as string
        self.radVar.set(rad)

    def updateSlide(self, *event):
        if not self.radVar.get():#if entry is an empty string, set slider to zero
            value = 0
        else:
            value = int(self.radVar.get())
        self.radSlider.set(value)        

    def validateInt(self, action, index, value_if_allowed, prior_value, text, *args):
    """
    validates an entry to integers and empty string only
    """
        if (value_if_allowed == ""):
            return True
        if text in '0123456789':
            try:
                int(value_if_allowed)
                return True
            except:
                return False
        else:
            return False

它工作正常,但是当radEntry是一个空字符串时:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1410, in __call__
    return self.func(*args)
  File "C:\Users\ntopper\Desktop\Collector\NewObjDialog.py", line 127, in update Slide
    if not self.radVar.get():
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 283, in get
    return getint(self._tk.globalgetvar(self._name))
ValueError: invalid literal for int() with base 10: ''

一种解决方法是永远不允许该条目为空字符串,但在输入框中删除零是一种令人不快的感觉。 (要将框设置为241,首先将框设置为410,然后设置为41,然后设置为241)

另一种选择只是忽略错误消息,因为它不会使我的程序崩溃,但这有点草率。

似乎Tkniter.StringVar()。get()试图将它自己的字符串值强制转换为整数,为什么会这样?

1 个答案:

答案 0 :(得分:1)

这是我刚刚为空闲对话框编写的更简单的is_int(或空白)Entry验证器。

# at module level
def is_int(s):
    "Return 's is blank or represents an int'"
    if not s:
        return True
    try:
        int(s)
        return True
    except ValueError:
        return False
...
# inside widget_subclass.__init__
       self.is_int = self.register(is_int)
...
# inside widget_subclass method
           Entry(entry_area, textvariable=var, validate='key',
                 validatecommand=(self.is_int, '%P')  
                ).grid(row=row, column=1, sticky=NSEW, padx=7)

至于你的错误,我修复了如此的验证文档字符串缩进

    def validateInt(self, action, index, value_if_allowed, prior_value, text, *args):
        """validates an entry to integers and empty string only"""
        if value_if_allowed == "":

并在Win7上以2.7.8运行,您的代码工作正常,没有错误消息。更改滑块或文本会改变另一个,如您所设计的那样。

查看我的Python27\lib\lib-tk\Tkinter.py副本,

    return getint(self._tk.globalgetvar(self._name))

位于IntVar.get方法内的第321行,我在此预期。与上面的追溯一样,第283行位于StringVar.__init__文档字符串中。所以我最好的猜测是你运行的是早期版本的2.x,并且你的Tkinter.py副本有一个严重的错误。

相关问题