При печати текста Entry последний символ удаляется.Как исправить? - PullRequest
0 голосов
/ 01 июня 2019

Я хочу напечатать текст записи каждый раз, когда пишется новый персонаж. При этом с привязкой и командой для виджета последний символ не печатается.

Я полагаю, что параметр textvariable обновляется после выполнения команды привязки. Как это исправить?

from tkinter import *
master = Tk()
var = StringVar()

def execute_e(key):
    print(var.get())

E = Entry(master, width=30, textvariable=var)
E.pack()
E.bind('<Key>', execute_e)

Ответы [ 2 ]

1 голос
/ 01 июня 2019

Это потому, что функция привязанного события выполняется до добавления нового ключа.

Вот простой обходной путь, который использует возможность добавления проверки к виджету Entry (валидатор принимает любой ключ, потому что он всегда возвращает True). Хитрость заключается в том, что функция validator настроена на получение значения, которое будет иметь текст , если изменение разрешено путем указания %P, когда его конфигурация является частью конструкции Entry через validatecommand=(validator_command, '%P').

Вот некоторая документация о добавлении проверки к Entry виджетам с подробностями о том, как она работает.

from tkinter import *

master = Tk()
var = StringVar()

def validator(new_value):
    print(f'new_value: {new_value}')
    return True

validator_command = master.register(validator)

E = Entry(master, width=30, textvariable=var,
          validate='key',
          validatecommand=(validator_command, '%P'))
E.pack()

master.mainloop()
0 голосов
/ 01 июня 2019

Мне кажется, что это вопрос обработчика событий.Когда клавиша набрана, ваш код сначала регистрирует нажатие клавиши и выполняет связанную команду execute_e.Только после того, как он обработает это, и ваш обработчик события возвратит, он обновит запись с символом и приступит к обновлению переменной tkinter.

Поэтому ваша команда печати поступает до того, как ваша переменная была обновлена, и вы печатаетепредыдущая версия вашей переменной.Если вы попытаетесь удалить символ из своей записи, вы увидите, что вы получите предыдущую строку с только что удаленным символом.

Самый простой способ решить эту проблему для вас - это, вероятно, связать команду сПеременная tkinter, а не связка ключей.Делайте это, используя trace, когда переменная записывается следующим образом:

var.trace('w', execute_e)

Существуют также некоторые методы для управления обработчиком событий и выбора порядка выполнения команд.root.after_idle выполнит команду, когда коду больше нечего делать (когда он вычислил все остальное, что вы просили сделать).Попробуйте эту версию своего кода:

from tkinter import *
master = Tk()
var = StringVar()

def execute_e(*key):
    def printy():
        print(var.get())
    master.after_idle(printy)

E = Entry(master, width=30, textvariable=var)
E.pack()
E.bind('<Key>', execute_e)
master.mainloop()
...