Seite 1 von 1
Timer mit wiederkehrender Aufgabe
Verfasst: Sonntag 5. Juli 2020, 08:56
von delphinis
Hallo,
möchte eine wiederkehrende Aufgabe z.B. alle 5min erledigen (zum Test nur 5s). Hab dabei mehrere Beispiele gefunden, die alle gleich aussehen, aber so nicht funktionieren.
Folgender Code sollte alle 5s das Popup-Fenster infoMsg() aufpoppen. Aber es wird nur einmal gleich beim Start aufgepoppt und dann nie mehr...
Code: Alles auswählen
from tkinter import *
import threading
root = Tk()
root.geometry('100x100+-7+0')
root.configure(background='black')
def infoMsg(msg):
popup = Tk()
titleLabel = Label(popup, text="Info", font='Arial_bold 15', fg="red")
titleLabel.pack(side="top", fill="both", pady=10)
label = Label(popup, text=msg)
label.pack(side="top", fill="both", pady=10)
B1 = Button(popup, text="Okay", command = popup.destroy)
B1.pack(side="top", fill="y", pady=10)
popup.mainloop()
class Window(Frame):
def __init__(self, master): #globale variable an
Frame.__init__(self,master)
global timer
timer = threading.Timer(5, infoMsg("Hello"))
timer.start()
app = Window(root)
app.pack(fill=BOTH, expand=YES)
root.mainloop()
Re: Timer mit wiederkehrender Aufgabe
Verfasst: Sonntag 5. Juli 2020, 08:59
von __deets__
Ich habe nichts von Timern gesagt. Sondern von after. Threading und GUIs funktioniert nicht.
Re: Timer mit wiederkehrender Aufgabe
Verfasst: Sonntag 5. Juli 2020, 09:35
von Sirius3
@delphinis: benutze kein global, keine *-Importe und von Tk darf es nur eine Instanz geben und nur einen Aufruf von mainloop. Dass Du so viele kaputte Beispiele gefunden hast, ist liegt wohl daran, dass Du an der falschen Stelle gesucht hast. Hier im Forum gibt es bestimmt 100 Beiträge, wo erklärt wird, wie es richtig funktioniert.
Re: Timer mit wiederkehrender Aufgabe
Verfasst: Sonntag 5. Juli 2020, 10:31
von delphinis
Ok, ich hab's nun so gelöst:
nach 5s rufe ich eine Methode auf die dann etwas tun soll, und diese startet gleich wider die after methode mit sich selbst als callback routine.
Hoffe das ist so auch korrekt, da es ja kein rekursiver aufruf im eigentlichen Sinne ist...
Code: Alles auswählen
from tkinter import *
root = Tk()
root.geometry('200x200+-7+0')
def periodic_work():
print("doing something")
root.after(5000, periodic_work)
class Window(Frame):
def __init__(self, master): #globale variable an
Frame.__init__(self,master)
root.after(5000, periodic_work)
app = Window(root)
root.mainloop()
Re: Timer mit wiederkehrender Aufgabe
Verfasst: Sonntag 5. Juli 2020, 10:34
von __deets__
So macht man das, ja.
Re: Timer mit wiederkehrender Aufgabe
Verfasst: Sonntag 5. Juli 2020, 10:46
von Sirius3
Das ist aus den oben genannten Gründen nicht sauber gelöst.
Window ist auch nur ein Frame und kein Fenster.
Code: Alles auswählen
import tkinter as tk
class Window(tk.Frame):
def __init__(self, master):
super().__init__(master)
self.after(5000, self.periodic_work)
def periodic_work(self):
print("doing something")
self.after(5000, self.periodic_work)
def main():
root = tk.Tk()
root.geometry('200x200+-7+0')
app = Window(root)
root.mainloop()
if __name__ == '__main__':
main()
Re: Timer mit wiederkehrender Aufgabe
Verfasst: Sonntag 5. Juli 2020, 15:09
von __blackjack__
Noch die übliche Anmerkung das `super()` hier falsch ist und nicht funktioniert weil `Frame` auch kein `super()` verwendet. Falls es das täte müsste man noch beliebige zusätzliche Argumente und Schlüsselwortargumente akzeptieren und weiterreichen. `super()` ist superkompliziert.
Re: Timer mit wiederkehrender Aufgabe
Verfasst: Dienstag 7. Juli 2020, 12:21
von delphinis
__blackjack__ hat geschrieben: Sonntag 5. Juli 2020, 15:09
Noch die übliche Anmerkung das `super()` hier falsch ist und nicht funktioniert weil `Frame` auch kein `super()` verwendet. Falls es das täte müsste man noch beliebige zusätzliche Argumente und Schlüsselwortargumente akzeptieren und weiterreichen. `super()` ist superkompliziert.
Funktioniert doch. Aber ohne super() funktioniert es aber auch nicht (wenn man die ganze Zeile streicht). Offenbar muss man den Vorfahren doch auch initialisieren?
Re: Timer mit wiederkehrender Aufgabe
Verfasst: Dienstag 7. Juli 2020, 17:12
von __blackjack__
@delphinis: Natürlich muss man die `__init__()` der Basisklasse aufrufen, aber mit `super()` ist das halt falsch. Und ”funktioniert doch” stimmt halt nur solange bis das dann mal jemand für das benutzen will wofür es eigentlich da ist.
Re: Timer mit wiederkehrender Aufgabe
Verfasst: Dienstag 7. Juli 2020, 17:21
von delphinis
Ok, ich glaub ich hab's mittlerweile auch kapiert. Ein richtig initialisiertes Hauptfenster das auch seine Referenz mit gibt (zwecks z.B. eines hinzufügens eines Buttons) sollte dann wohl etwa so aussehen:
Code: Alles auswählen
import tkinter as tk
from tkinter import Tk, RIGHT, BOTH, RAISED, YES
from tkinter.ttk import Frame, Button, Style
class Window(Frame):
def __init__(self, master):
Frame.__init__(self,master)
self.master.title("Program name")
self.master.geometry('300x150+-7+0')
self.style = Style()
self.style.theme_use("default")
root = tk.Tk()
app = Window(root)
app.pack(fill=BOTH, expand=YES)
root.mainloop()