2012-12-27 2 views
0

Я разрабатываю кадр «настроек» для приложения Python/Tkinter, которое позволяет пользователю указать IP-адрес, номер порта и пару других настраиваемых параметров. Я хочу проверить данные пользователя, прежде чем позволить пользователю закрыть рамку, чтобы применить их.Должна ли быть проверена проверка Tkinter?

Исходя из того, что я читал на (и пробовал) до сих пор с Entry виджета validate и validatecommand варианты, единственные выборы, которые они предлагают «тяжеловесный» валидация. Тип, в котором пользователь заблокирован, оставляя виджет ввода (или даже набрав больше нажатий клавиш), пока запись не будет действительна. Это именно то поведение, которое я избегаю при разработке графического интерфейса, потому что это раздражает, поскольку все выходы для пользователя.

Я планирую переключиться на использование методов .trace, чтобы следить за значениями и просто отключить кнопку «ОК/Применить» до тех пор, пока все записи в кадре не будут действительны. Прежде чем я это сделал, я хотел знать, не хватает ли я чего-либо в отношении встроенных параметров проверки. Есть ли вариант, который я пропустил, это менее тяжело?

+0

Можно ли установить обратный вызов ['invalidcommand'] (http://www.tcl.tk/man/tcl8.4/TkCmd/entry.htm#M16), который переносит тяжесть? –

ответ

1

Я не уверен, что вы должны это сделать, но вы можете подключить обработчик invalidcommand, который будет действовать на запись , как если бы все было в порядке.

Пример сценарий:

import Tkinter as tk 

def onvalidate(d,i,P,s,S,v,V,W): 
    # only lowercase is valid 
    valid = (P.lower() == P) 
    # set red background if invalid 
    newcolor = 'red' if not valid else default_color 
    root.nametowidget(W).configure(background=newcolor) 
    return valid 

def oninvalid(d,i,P,s,S,v,V,W): 
    #called if widget is invalid 
    widget = root.nametowidget(W) 
    # S is the character that *would* have been 
    # inserted or deleted, but won't because it is invalid 
    # So we do it ourselves 
    if S: 
     if d=='0': 
      widget.delete(i, len(S)) 
     elif d=='1': 
      widget.insert(i, S) 
    # Changing the text clears the 'validate' value 
    # so we have to reset it 
    widget.after_idle(lambda W,v: root.nametowidget(W).configure(validate=v), W, v) 

root = tk.Tk() 

valhook = (root.register(onvalidate), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W') 
invhook = (root.register(oninvalid), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W') 

entry = tk.Entry(root, validate="key", validatecommand=valhook, invalidcommand=invhook) 

default_color = entry.cget('background') 

entry.pack() 

root.mainloop() 

Это создаст запись, которая будет иметь красный фон, если недействительны и белый фон, если нет, но текст все равно будет вставлен или удален, даже если запись недействительна.

+0

Это хорошо, я использовал аналогичный подход в своих старых приложениях VB6 - не совсем понял, как это сделать в Tkinter. Благодаря! – JDM

1

Если вы используете трассировку, то у вас есть то, что вы хотите, без использования валидации Tkinter вообще. Сделайте все трассы в той же функции, где вы проверяете и проверяете все свои значения по своему усмотрению и в соответствии с этим включаете или выключаете кнопку ok.

+0

Я понял, что - я просто хотел знать, была ли проверка Tkinter жизнеспособной, прежде чем я переключился. – JDM

2

Вы можете использовать функцию проверки без «тяжеловесности». Если вы подтвердите правильность положения кнопки ok/apply, подтвердите свое подтверждение.

+0

Спасибо, я бы не подумал об этом. Я могу просто указать все виджеты Entry на одну и ту же общую процедуру (например, я планировал настроить альтернативу с трассировкой). – JDM

Смежные вопросы