Seite 1 von 1

Tkinter Validierung eines Timecodes funktioniert nicht

Verfasst: Mittwoch 5. April 2023, 08:45
von mrrockkz
Hallo zusammen,

ich habe folgenden Code um nur die Eingabe eines gültigen Timecodes zu erlauben, jedoch kann ich den Doppelpunkt nicht selbst eingeben (was ich jedoch gerne tun würde). Sobald ich drei Zahlen eingebe und die dritte Zahl dadurch automatisch mit einem Doppelpunkt ersetzt wird, setzt die Validierung komplett aus und ich kann fortlaufend eintragen was ich will, weil die Validierung nicht mehr funktioniert. Worin kann der Fehler liegen?

Code: Alles auswählen

        runtime_label = tk.Label(metadata_window, text="Runtime (01:30:20:10):", background=GUI_BG_COLOR,
                                 foreground=GUI_TEXT_COLOR)
        runtime_label.pack(padx=0, pady=8)
        self.runtime_entry = tk.Entry(metadata_window, background="#333333", foreground=GUI_TEXT_COLOR, width=42,
                                      textvariable=runtime_var, validate="key")
        self.runtime_entry.pack()
        validate_runtime_entry_command = metadata_window.register(self.validate_runtime_entry)
        self.runtime_entry.config(validatecommand=(validate_runtime_entry_command, '%S'))


    def validate_runtime_entry(self, input):
        time_str = self.runtime_entry.get().strip()
        if input.isdigit() and len(time_str.replace(':', '')) < 8:
            # Add colon after every two digits
            if len(time_str.replace(':', '')) in [2, 4, 6]:
                self.runtime_entry.insert(len(time_str), ':')
            return True
        elif input == '\b':
            return True
        else:
            try:
                # Check format first
                datetime.datetime.strptime(time_str, '%H:%M:%S:%f')
                # Then check if it's a valid time
                h, m, s, f = map(int, time_str.split(':'))
                if not (0 <= h <= 23 and 0 <= m <= 59 and 0 <= s <= 59 and 0 <= f <= 47):
                    raise ValueError
                return True
            except ValueError:
                return False

Re: Tkinter Validierung eines Timecodes funktioniert nicht

Verfasst: Mittwoch 5. April 2023, 09:18
von __deets__
Ich habe da keine persönliche Erfahrung, aber was du da tust ist im Zweifel einfach illegal. Das system befindet sich gerade in einer validierung, und du hackst in der validierung neuen Inhalt rein, der dann eine validierung erfordert….

Laut https://anzeljg.github.io/rin2/book2/24 ... ation.html ging es ein invalidcommand, das explizit erlaub Änderungen zu machen, wenn die validierung daneben ging. Versuch deine doppelpunkterei darauf umzustellen.

Re: Tkinter Validierung eines Timecodes funktioniert nicht

Verfasst: Mittwoch 5. April 2023, 20:46
von mrrockkz
__deets__ hat geschrieben: Mittwoch 5. April 2023, 09:18 Ich habe da keine persönliche Erfahrung, aber was du da tust ist im Zweifel einfach illegal. Das system befindet sich gerade in einer validierung, und du hackst in der validierung neuen Inhalt rein, der dann eine validierung erfordert….

Laut https://anzeljg.github.io/rin2/book2/24 ... ation.html ging es ein invalidcommand, das explizit erlaub Änderungen zu machen, wenn die validierung daneben ging. Versuch deine doppelpunkterei darauf umzustellen.
Danke. Selbst wenn ich die Ergänzung mit den Doppelpunkten aus dem Code entferne, funktioniert es nicht. Ich kann dann gar nichts mehr in das Feld eintippen.
Ich erkenne den Fehler leider nicht :cry:

Re: Tkinter Validierung eines Timecodes funktioniert nicht

Verfasst: Donnerstag 6. April 2023, 10:08
von __deets__
Da du per key abfragst, kann man ja auch nie eine gueltige Eingabe machen. Du musst focusout benutzen.

Re: Tkinter Validierung eines Timecodes funktioniert nicht

Verfasst: Samstag 8. April 2023, 12:08
von mrrockkz
__deets__ hat geschrieben: Donnerstag 6. April 2023, 10:08 Da du per key abfragst, kann man ja auch nie eine gueltige Eingabe machen. Du musst focusout benutzen.
Danke. Leider funktioniert das nicht, sobald es irgendwie "komplizierter wird". Mit "focusout" tut sich leider garnichts.

Nun habe ich es so gelöst.

Code: Alles auswählen

        creditstart_label = tk.Label(metadata_window, text="Creditstart (01:20:10:00):", background=GUI_BG_COLOR,
                                     foreground=GUI_TEXT_COLOR)
        creditstart_label.pack(padx=0, pady=8)
        self.creditstart_entry = tk.Entry(metadata_window, background="#333333", foreground=GUI_TEXT_COLOR, width=42,
                                          textvariable=creditstart_var, validate="key")
        self.creditstart_entry.pack()
        validate_creditstart_entry_command = metadata_window.register(self.validate_creditstart_entry)
        self.creditstart_entry.config(validatecommand=(validate_creditstart_entry_command, '%S'))

    @staticmethod
    def validate_runtime_entry(text):
        if text == "":
            return True

        allowed_chars = set(":0123456789")
        if set(text) <= allowed_chars:
            return True

        return False
Jedoch zerschießt es später das Programm sobald man ausversehen eine Ziffer zu viel oder zu wenig eingibt, da irgendwann die Doppelpunkte aufgelöst werden (sodass es noch 8 Ziffern sind) und in einem anderen Programm werden die Doppelpunkte wieder eingefügt - jedoch funktioniert das nicht zuverlässig bei einer Falscheingabe. Ich bekomme es leider überhaupt nicht gelöst und verzweifle daran. :cry:

Hat hier jemand evtl. einen anderen Lösungsansatz?

Re: Tkinter Validierung eines Timecodes funktioniert nicht

Verfasst: Samstag 8. April 2023, 12:19
von __blackjack__
`validate_runtime_entry()` ist recht kompliziert geschrieben. Was da letztlich gemacht wird ist das hier:

Code: Alles auswählen

    @staticmethod
    def validate_runtime_entry(text):
        return set(text) <= set(":0123456789")
Den ersten Test ob `text` leer ist, kann man sich sparen, weil der in dem Mengentest enthalten ist. Die leere Menge ist Teilmenge von jeder Menge.

Re: Tkinter Validierung eines Timecodes funktioniert nicht

Verfasst: Samstag 8. April 2023, 12:35
von mrrockkz
__blackjack__ hat geschrieben: Samstag 8. April 2023, 12:19 `validate_runtime_entry()` ist recht kompliziert geschrieben. Was da letztlich gemacht wird ist das hier:

Code: Alles auswählen

    @staticmethod
    def validate_runtime_entry(text):
        return set(text) <= set(":0123456789")
Den ersten Test ob `text` leer ist, kann man sich sparen, weil der in dem Mengentest enthalten ist. Die leere Menge ist Teilmenge von jeder Menge.
Danke dir, das macht das auf jeden Fall schöner :lol:
Löst leider mein Problem nicht ganz :(

Re: Tkinter Validierung eines Timecodes funktioniert nicht

Verfasst: Samstag 8. April 2023, 13:30
von __deets__
Nachdem ich damit rumgespielt habe, bekomme ich tatsaechlich kein Rueckruf bei focusout. Womit das feature einfach am Arsch ist. Denn auf einzelner Tastendruck-Ebene kann man das nicht vernuenftig validieren. So aergerlich das ist. Dann bleibt wohl nur eine von zwei Moeglichkeiten:

- eigene Validierung, zB indem du einen Dialog machst, und beim "Ok" oder was auch immer die Aktion ist, die Werte pruefst, und dann die Weiterverarbeitung ablehnst, wenn das nicht die passende Eingabe enthaelt.
- Wechseln zu einem GUI-Toolkit, was das kann. Qt zB.

Re: Tkinter Validierung eines Timecodes funktioniert nicht

Verfasst: Samstag 8. April 2023, 17:12
von juwido
Hallo, ja, sollte einfacher sein, die Validierung im Anschluß an die Eingabe komplett in Python zu erledigen. Der Weg über die tcl-Methoden ist wohl nicht so gut von tkinter unterstützt.