Первой очевидная проблема эта линия:
?
tutor_var.trace('w', lambda name, index, mode: validate_enter_0_2)
Вы создали функцию, которая принимает три переменные, и возвращает функцию validate_enter_0_2
как объект функции. Это не делает ничего хорошего.
Вы хотите создать функцию, которая звонитvalidate_enter_0_2
функция. Как это:
tutor_var.trace('w', lambda name, index, mode: validate_enter_0_2())
У вас есть точно такая же проблема с name_var
и будет также необходимо зафиксировать его там, конечно.
Кроме того, вы на самом деле не имеют функция с именем validate_enter_0_2
называть, потому что вы определили его как validate_enter_2
. Это означает, что ваша функция проверки просто добавляет NameError
вместо того, чтобы делать полезные действия. Или, если у вас есть функция validate_enter_2
, определенная где-то еще в вашем коде, она вызывает неправильную функцию. (Это одна из причин, что загадочные имена, как enter_0_2
и enter_2
не очень хорошая вещь.)
Там, по крайней мере одна другая проблема с кодом: Вы неоднократно пытался использовать name_var
, который является StringVar
объект , как если бы это была строка. Вы не можете этого сделать. И если вы на самом деле смотреть на выходе консоли Tkinter расскажет вам об этом, с tracebacks, как это:
Exception in Tkinter callback
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1410, in __call__
return self.func(*args)
File "tkval2.py", line 25, in callback
if len(name_var) > 10 or any(l not in string.ascii_letters for l in name_var):
AttributeError: StringVar instance has no attribute '__len__'
И это исключение происходит, прежде чем вы получите возможность создать новый Entry
.
Чтобы исправить это, вам нужно позвонить get
на StringVar
всякий раз, когда вы хотите получить его значение, например:
if len(name_var.get()) > 10 or any(l not in string.ascii_letters for l in name_var.get())
Наконец, как я объяснил в ответ на ваш другой вопрос, ваш валидатор trace
не будет вызван, пока что-то не изменится. Это означает, что вам нужно либо вызвать его явно, либо явно name_var.set('')
, либо просто отключить кнопку. Как написано, он будет включен, и только отключите, если вы напечатаете что-то, а затем удалите его.
Я не уверен, является ли это единственные проблемы с вашим кодом, но все они, безусловно, предотвратить вашу проверку работать, как ожидалось.Таким образом, вам нужно исправить все их и любые другие ошибки в коде, прежде чем он будет работать.
Из ваших комментариев:
Однако я задавался вопросом, как создать всплывающее сообщение об ошибке, отображающее ...
Когда вы хотите сделать это? Какое условие вы хотите проверить, и когда вы хотите его проверить?
Во всяком случае, как и в большинстве графических интерфейсов, способ «всплывать» - это диалог. Dialog Windows в книге Tkinter объясняет все, что вам нужно знать. Но вам не нужно копировать-вставлять весь этот код или писать его с нуля; stdlib поставляется с Tkinter helper modules, которые выполняют большую часть работы для вас. В вашем случае вы, вероятно, просто хотите tkMessageBox
.
... и что-то, что заставляет пользователя повторно ввести их имя
принуждать их как? Просто удаление существующего содержимого Entry оставит их с пустым полем для заполнения, что также отключит кнопку. Это то, что вы хотите?
Во всяком случае, догадываясь, что вы хотите, это может выглядеть примерно так:
def callback():
if len(name_var.get()) > 10:
tkMessageBox.showerror("Bad name", "Your name is too long. What's wrong with good American names like Joe?")
name_var.set('')
return
# the rest of your code here
В callback
функции (вызывается при нажатии на кнопку после ввода их имя), вместо того, чтобы просто проверить некоторое условие и распечатав что-то, я проверяю условие и вывожу диалоговое окно с ошибкой, очищаю существующее имя и возвращаю раньше, а не создаю вторую половину формы. Я не обрабатывал ваше другое условие (любые буквы, отличные от ASCII), но должно быть очевидно, как добавить это.
Однако подтверждение такого действия может быть сделано лучше всего посредством фактической проверки - вместо того, чтобы заставить их ждать, пока они не нажмут кнопку, поймайте его, как только они попытаются ввести 11-й символ, или пробел или акцентированный символ, или что-то еще иначе вам не понравится. Затем вы можете открыть окно сообщения и либо отключить кнопку, пока не исправит ее, не отклоните/не отмените изменение (что проще с функцией validatecommand
, чем с функцией trace
, как показано в ответе на ваш предыдущий вопрос).
Последнее: Вместо окна сообщения может быть лучше просто вставить ошибку, как, например, ярлык, который появляется в самой форме (возможно, с описанием ошибки в красном цвете с большим значком) , Это распространено в веб-приложениях и в более современных графических интерфейсах, поскольку обеспечивает более немедленную обратную связь и менее навязчиво для пользовательского потока.
http://stackoverflow.com/questions/16687124/python-tkinter-disable-the-button-until-all-the-fields-are-filled –
Подразумевается ли это как [предыдущий вопрос] http://stackoverflow.com/questions/20622044/how-to-i-create-an-event-for-user-entry/20622282#comment31391807_20622282), или совершенно новый вопрос, который каким-то образом отличается? (И, если последнее, каким образом оно отличается?) – abarnert
Кроме того, как я уже говорил вам по предыдущему вопросу, предоставьте [SSCCE] (http://sscce.org) - что-то, что мы можем запустить и отладить Вместо простого фрагмента кода. – abarnert