Python tkinter не удалит запись, удалит только все, кроме последнего символа

Я впервые программирую, пожалуйста, будьте полегче.

Я пытаюсь создать приложение, которое будет принимать 5 разных записей. После нажатия кнопки я хочу, чтобы эти записи были очищены. Сейчас я тестирую только один — «lditime». У меня установлен ввод так, что он принимает только (XX:XX:XX) и больше никаких символов и пробелов, где X — цифра.

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

import tkinter as tk

window = tk.Tk()

def validate_time(inputtime):
    if len(inputtime) == 1 and inputtime[-1].isdigit():
        return True
    if len(inputtime) == 2 and inputtime[-1].isdigit():
        return True
    if len(inputtime) == 3 and inputtime[-1] == ":":
        return True
    if len(inputtime) == 4 and inputtime[-1].isdigit():
        return True
    if len(inputtime) == 5 and inputtime[-1].isdigit():
        return True
    if len(inputtime) == 6 and inputtime[-1] == ":":
        return True
    if len(inputtime) == 7 and inputtime[-1].isdigit():
        return True
    if len(inputtime) == 8 and inputtime[-1].isdigit():
        return True
    else:
        return False

def on_validate(P):
    return validate_time(P)

def backandmessage(bs):
    if bs.keysym == "BackSpace":
        return "break"
    messagecheck()  #cmd that is irrelevant

def ldrelease():
    if (len(lditime.get()) == 8 and len(ldilat.get()) == 8 and len(ldilong.get()) == 8 and
            ((ldd1cbv.get() == 1 or ldd2cbv.get() == 1) or ldd3cbv.get() == 1 or ldd4cbv.get() == 1
             or ldd5cbv.get() == 1 or ldd6cbv.get() == 1)):
        lditime.delete(0, 8)
        ldd1.deselect()
        ldd1.configure(state = "normal")
        ldd2.deselect()
        ldd2.configure(state = "normal")
        ldd3.deselect()
        ldd3.configure(state = "normal")
        ldd4.deselect()
        ldd4.configure(state = "normal")
        ldd5.deselect()
        ldd5.configure(state = "normal")
        ldd6.deselect()
        ldd6.configure(state = "normal")


ldi = tk.Label(text = "Load Drop Interface", font=("Helvetica", 15))
lditimet = tk.Label(text = "Time", font=("Helvetica", 15))
lditime = tk.Entry(validate = "key", validatecommand=(window.register(on_validate), "%P"))
lditime.bind("<KeyPress>", backandmessage)
lddrelease = tk.Button(text = "Release", font=("Helvetica", 15), command=ldrelease)

window.mainloop()

Я пробовал использовать lditime.delete(0, 8), как указано выше, lditime.delete(0, tk.END). Когда я использую lditime.delete(0, 7), он очищает все символы записи, кроме последнего. Когда я печатаю len(lditime.get()), получается 8. Когда я распечатываю его посимвольно, все происходит так, как и ожидалось (в качестве теста я использовал 12:12:12). Я пробовал использовать lditime.focus_force() перед удалением.

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

    print(lditime.get())
    print(len(lditime.get()))
    lditime.delete(0, 8)
    print(lditime.get())
    print(len(lditime.get()))

Что дало мне 8, 12:12:12, 8, 12:12:12. Когда я повторил это с помощью lditime.delete(0, 7), получилось 8, 12:12:12, 2, 1.

Я потратил часы. Пожалуйста, помогите мне.

вам может понадобиться <KeyRelease> вместо <KeyPress>. Насколько я помню, KeyPress мой код запуска до того, как он вставит новый символ Entry, и KeyRelease может запустить код после того, как он вставит новый символ Entry

furas 21.04.2024 20:46

@furas, спасибо, но все равно удалю все, кроме последнего с 7, и ничего с 8/tk.END. как раз собираюсь отредактировать, чтобы добавить код команды backandmessage

jsmoth0990 21.04.2024 21:01

возможно, сначала используйте print(), чтобы увидеть, какая часть кода выполняется и что у вас есть в переменных. Возможно, он выполняется до того, как tkinter вставит последний символ Entry. Или он одновременно выполняет другую функцию и добавляет последний символ. если бы вы создали минимальный рабочий код, мы могли бы проверить эту проблему на наших компьютерах. Возможно, эта проблема существует только в некоторых системах (WIndows, Linux, MacOS).

furas 23.04.2024 00:08
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

это тест, попробуйте разобрать его один за другим и выяснить или написать тестовый сценарий

            import tkinter as tk

            def clear_entry():
                print("Widget state before clear:", entry['state'])  # Check widget state
                print("Content before clear:", entry.get())  # Log content before clearing
                entry.delete(0, tk.END)  # Attempt to clear the entry
                print("Content after clear:", entry.get())  # Log content after clearing

            root = tk.Tk()
            entry = tk.Entry(root)
            entry.pack()
            entry.insert(0, "12:34:56")  # Inserting example data

            clear_button = tk.Button(root, text = "Clear", command=clear_entry)
            clear_button.pack()

            root.mainloop()

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

и вот возможный обходной путь:

            import tkinter as tk

            window = tk.Tk()

            lditime_var = tk.StringVar()
            lditime = tk.Entry(window, textvariable=lditime_var)
            lditime.pack()

            def clear_entry():
                lditime_var.set('')  # Clear the entry by setting its linked StringVar to an empty string

            clear_button = tk.Button(window, text = "Clear", command=clear_entry)
            clear_button.pack()

            window.mainloop()

Эта функция устанавливает содержимое lditime_var в пустую строку. Поскольку lditime связан с этим StringVar, изменение значения lditime_var автоматически обновляет текст, отображаемый в виджете Entry.

Спасибо, но я упомянул в сообщении, что пробовал lditime.delete(0, 8), lditime.delete(0, tk.END) и lditime.delete(0, len(lditime.get()). Они все просто отказался очистить его.

jsmoth0990 22.04.2024 15:11

Вопрос 1. Как ведет себя запись, когда вы удаляете привязки событий и другие взаимодействия. Вопрос 2. Можете ли вы предоставить более подробную информацию о том, что делает messagecheck(), и о любом другом коде, который взаимодействует с lditime? Вопрос 3. Существуют ли другие части вашего кода, которые могут изменять состояние или содержимое виджета «Ввод» или взаимодействовать с ним вне операции удаления?

user24548854 23.04.2024 05:29
Ответ принят как подходящий

Когда вы вызываете lditime.delete(0, 8), функция проверки validate_time() вернет False, потому что inputtime — пустая строка. Так что ничего не будет удалено.

Вам нужно вернуть True, когда inputtime пустая строка:

def validate_time(inputtime):
    if len(inputtime) == 0:
        return True
    ...

Это сделало это! Большое вам спасибо! Я чувствовал, что это может иметь какое-то отношение к этому, но просто не мог понять этого.

jsmoth0990 23.04.2024 09:25

Другие вопросы по теме