Fehler beim Beenden der TKinter GUI

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
pippsen
User
Beiträge: 7
Registriert: Dienstag 28. Januar 2020, 11:07

Hallo zusammen,

wenn ich meine Gui über das das "X" beende bekomme ich immer einen Fehler angegeben. Sobald ich es aber über root.mainloop() programmiere und meinen zyklischen Aufruf nicht v verwende funktioniert es.

Könnte mir jemand Hilfe geben woran das liegt?

Beste Grüße

Code: Alles auswählen

from tkinter import *
from tkinter import messagebox
import time
from datetime import datetime


def on_closing():
    if messagebox.askokcancel("Beenden", "Wollen Sie wirklich das Programm beenden?"):
        global running
        running = FALSE
        root.destroy()

# Main Window
root = Tk()
root.geometry("595x500+300+300")
root.wm_resizable(width=False, height=False)
root.title("TestGUI")

menu = Menu(root)
root.config(menu=menu)
statusbar = Label(root, text="", bd=1, relief=SUNKEN, anchor=W)
statusbar.pack(side=BOTTOM, fill=X)

running = True

def main():
    while running:
        root.update_idletasks()
        root.update()
        time.sleep(0.5)
        lt = '{:%d.%m.%Y %H:%M:%S}'.format(datetime.now())
        statusbar['text'] = lt
        root.protocol("WM_DELETE_WINDOW", on_closing)



if __name__ == '__main__':
    main()

Code: Alles auswählen

D:\Privat\PyCharm\Countdown\venv\Scripts\python.exe C:/Users/xxx/.PyCharmCE2019.3/config/scratches/scratch_13.py
Traceback (most recent call last):
  File "C:/Users/xxx/.PyCharmCE2019.3/config/scratches/scratch_13.py", line 38, in <module>
    main()
  File "C:/Users/xxx/.PyCharmCE2019.3/config/scratches/scratch_13.py", line 32, in main
    statusbar['text'] = lt
  File "D:\Privat\Python\lib\tkinter\__init__.py", line 1648, in __setitem__
    self.configure({key: value})
  File "D:\Privat\Python\lib\tkinter\__init__.py", line 1637, in configure
    return self._configure('configure', cnf, kw)
  File "D:\Privat\Python\lib\tkinter\__init__.py", line 1627, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: invalid command name ".!label"

Process finished with exit code 1
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann lass das doch. Man treibt den mainloop nicht selbst. Wenn du einen Timer willst, benutz die after-Funktion respektive Methode.
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Benutze keine *-Importe, keine globalen Variablen. Auch alles, was unter # Main Window steht, sollte in der Funktion `main` stehen.

Code: Alles auswählen

import tkinter as tk
from tkinter import messagebox
from datetime import datetime
from functools import partial

def update(statusbar):
    statusbar['text'] = '{:%d.%m.%Y %H:%M:%S}'.format(datetime.now())
    statusbar.after(500, update, statusbar)

def on_closing(root):
    if messagebox.askokcancel("Beenden", "Wollen Sie wirklich das Programm beenden?"):
        root.destroy()

def main():
    root = tk.Tk()
    root.geometry("595x500+300+300")
    root.wm_resizable(width=False, height=False)
    root.title("TestGUI")
  
    menu = tk.Menu(root)
    root.config(menu=menu)
    statusbar = tk.Label(root, text="", bd=1, relief=tk.SUNKEN, anchor=tk.W)
    statusbar.pack(side=tk.BOTTOM, fill=tk.X)
    update(statusbar)
    root.protocol("WM_DELETE_WINDOW", partial(on_closing, root))
    root.mainloop()

if __name__ == '__main__':
    main()
Jedes nicht-triviale GUI-Programm braucht aber Klassendefinitionen, denn um beim Beenden den after-Loop ordnungsgemäß zu beenden, muß der Rückgabewert von after irgendwo gespeichert werden.
Antworten