使用颜色的Python Tkinter文本输入验证

时间:2015-01-03 22:52:30

标签: python validation textbox tkinter

我是Python和Tkinter的新手,我正在尝试使用颜色指示验证数字文本条目(黑色=有效条目;蓝色=有效,默认值;红色=无效条目)。我可以使用以下代码为每个条目显式执行此操作:

pdef = 14.7
p = 60

Label(parent, text="Pressure").grid(in_=frame_a,row=3, column=2, sticky='e')
p_entry = Entry(parent, width=8 ,textvariable=p, fg = pcolor)
p_entry.grid(in_=frame_a,row=3, column=3, padx=2, pady=2, sticky='we', columnspan=1)
p_entry.bind("<FocusOut>", validate)

def validate(event):
   global pcolor
   pmax = 30000
   pmin = 0
   y = p.get()

   if y == pdef:
       pcolor = 'blue'
   elif y < pmin or y > pmax:
       pcolor = 'red'
   else:
      pcolor = 'black'
   p_entry.config(fg = pcolor)  # explicitly set text color in p_entry textbox
   return(pcolor)

但是,我现在看到采用面向对象方法的价值,我可以将当​​前,高,低和默认值传递给validate方法并返回一个可以是3个值之一的标志。问题是我无法看到如何根据以通用而非显式方式返回的值将动作颜色应用于文本。

非常感谢任何帮助!

谢谢, 麦克

[编辑]

谢谢亚当。您的第一个示例显示了我想要做的事情。但是,我想将validate函数用于文本框验证的各种实例。我已根据您建议的部分功能调整了代码。这就是我的......

self.p['p_e'] = StringVar()
self.p['p_e'].set(14.7)       # Pressure

self.p_entry = Entry(root, width=8 ,textvariable=self.p['p_e'], fg = pcolor)
self.p_entry.bind("<FocusOut>", partial(self.color_changer,name = 'p_entry',
    y = float(self.p['p_e'].get()),max = 30000, min = 0, dft = 14.7))

def color_changer(self,event,name,y,max,min,dft):
   """entry validation Blue=default, Black=User, Red=Out of Range"""

   def validator(value):

      if value == dft:
         return -1
      elif value < min or value > max:
         return 0

   result = validator(y)          
   if result == -1:
      self.p_entry.config(fg = 'blue')
   elif result == 0:
      self.p_entry.config(fg = 'red')
   else:
      self.p_entry.config(fg = 'black')

我还有几个问题: 1)传递给颜色变化函数的字段值是初始化值,而不是触发<FocusOut>事件时的编辑值 2)我不确定如何将self.p_entry.config(上面的硬编码)替换为与文本输入实例绑定的通用变量(我传递&#39; name&#39;)

任何帮助表示赞赏! 谢谢, 麦克

1 个答案:

答案 0 :(得分:0)

请改为尝试:

from functools import partial
PMIN, PMAX = 0, 30000

def color_changer(event, pmin, pmax):

    def validator(value):
        if value < pmin:
            return -1
        if value > pmax:
            return 1
        else:
            return 0

    pressure = p.get()
    result = validator(pressure)
    if result == 0:
       p_entry.config(fg='black')
    else:
       p_entry.config(fg='red')

p_entry.bind("<FocusOut", partial(color_changer, pmin=PMIN, pmax=PMAX))

您的另一个选择可能是创建一个生成验证函数的闭包,并在回调中使用它。类似的东西:

from functools import partial

def validation_wrapper(test):
    def wrapped(value):
        return test(value)
    return wrapped

def color_changer(event, validation_test):
    pressure = p.get()
    result = validation_wrapper(validation_test)(pressure)
    if result:
        p_entry.config(fg='black')
    else:
        p_entry.config(fg='red')

between_min_and_max = lambda x: PMIN <= x <= PMAX
p_entry.bind("<FocusOut>", partial(color_changer, validation_test=between_min_and_max))

我实际上asked a question产生的回答与这种方法非常相似,不会太长。