Seite 1 von 1

sleep im Unterprogramm

Verfasst: Mittwoch 22. Juni 2022, 14:06
von Kobra23759
Hallo,
Ich benötige Hilfe bei fogenden Problem.
ich möchte mit tkinter ein Fenster erzeugen. In diesem Fenster soll eine gif angezeigt werden. Im UP1 soll nach einer bestimmten Zeit (dauer) dieses Bild (canvas1) gelöscht werden. wenn ich dieses Prog. ausführe erscheint das Fenster (fenster) erst nach der sleep(dauer)-Zeit.
Vielen Dank für die Hilfe

from tkinter import *
from time import time, sleep

def up1():
sleep(dauer)
canvas1.delete("all")

fenster=Tk()
fenster.geometry("350x455")

canvas1=Canvas(fenster,width=200,height=200)
canvas1.place(x=100, y=200)
bild=PhotoImage(file='c:\\temp\P3.gif')

canvas1.create_image(0,0,anchor=NW,image=bild)

dauer=5
up1()

fenster.mainloop()

Re: sleep im Unterprogramm

Verfasst: Mittwoch 22. Juni 2022, 14:32
von noisefloor
Hallo,

bei GUI-Frameworks _muss_ der Mainloop die Kontrolle behalten, d.h. du darfst ihn _nicht_ mit `sleep` blockieren. Das Stichwort heißt `after` Methode von tkinter. Dazu gibt es alleine hier im Forum Dutzend Threads.

Gruß, noisefloor

Re: sleep im Unterprogramm

Verfasst: Mittwoch 22. Juni 2022, 14:38
von __blackjack__
@Kobra23759: Sternchen-Importe sind Böse™. Bei `tkinter` holt man sich da um die 160 Namen ins Modul. Und nicht nur die, die in `tkinter` definiert werden, sondern auch die, die `tkinter` selbst wiederum von wo anders importiert. Es besteht die Gefahr von Namenskollisionen, und man sieht auch nicht mehr so leicht wo eigentlich welcher Name her kommt.

`time()` aus `time` wird importiert aber nirgends verwendet.

Auf Modulebene sollte nur Code stehen, der Konstanten, Funktionen, und Klassen definiert. Das Hauptrogramm steht üblicherweise in einer Funktion die `main()` heisst.

Funktionen bekommen alles was sie ausser Konstanten benötigen, als Argument(e) übergeben.

Das bedeutet, dass man bei GUI-Programmierung nicht um objektorientierte Programmierung (OOP) herum kommt. Oder zumindest `functools.partial()` für triviale Fälle.

Man nummeriert keine Namen. Man sich da entweder bessere Namen überlegen, oder keine Einzelnamen sondern eine Datenstruktur verwenden. Oft eine Liste. Hier ist das aber einfach nur sinnlos eine 1 an irgendwelche Namen zu hängen.

Man verwendet `place()` nicht. Genau so ist `geometry()` ein Problem. Absolute Grössen- und Positionsangeben funktionieren mit der heutigen Vielfalt an Bildschirmgrössen, -auflösungen, und -einstellungen nicht mehr.

`sleep()` und GUIs vertragen sich nicht, denn während Dein Code läuft, kann die GUI-Hauptschleife nicht laufen. Einfache Sachen erledigt man mit der `after()`-Methode auf Widget-Objekten.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk


def main():
    fenster = tk.Tk()

    canvas = tk.Canvas(fenster, width=200, height=200)
    canvas.pack()

    bild = tk.PhotoImage(file=R"c:\temp\P3.gif")
    canvas.create_image(0, 0, anchor=tk.NW, image=bild)

    fenster.after(5000, lambda: canvas.delete(tk.ALL))

    fenster.mainloop()


if __name__ == "__main__":
    main()

Re: sleep im Unterprogramm

Verfasst: Mittwoch 22. Juni 2022, 15:45
von Kobra23759
danke für deine Erklärungen. Vieleicht hast Du noch mal eine Min zeit für mich. Ich werde die Module jetzt so aufrufen.
Leider erkennt er jetzt dir Variable Fenster im Unterprogramm nicht. Über eine Antwort würde ich mich freuen
import tkinter as tk

def up():
fenster.after(600, lambda: canvas.delete(tk.ALL))

def main():
fenster = tk.Tk()
fenster.geometry("350x460")

canvas = tk.Canvas(fenster, width=200, height=200)
canvas.place(x=100, y=200)

bild = tk.PhotoImage(file=R"c:\temp\P3.gif")
canvas.create_image(0, 0, anchor=tk.NW, image=bild)

up()

fenster.mainloop()

if __name__ == "__main__":
main()

Re: sleep im Unterprogramm

Verfasst: Mittwoch 22. Juni 2022, 15:55
von __blackjack__
@Kobra23759: Woher sollte der Name auch kommen, der ist lokal in der `main()`-Funktion. Das nächste ist dann das auch `canvas` in `up()` nicht bekannt ist. Man müsste beides als Argumente übergeben. Aber warum überhaupt in eine Funktion auslagern?

Und `place()` und `geometry()` sind auch noch drin. Die `Canvas`-Grösse könnte/sollte man vielleicht auch von der Bildgrösse abhängig machen.

Re: sleep im Unterprogramm

Verfasst: Mittwoch 22. Juni 2022, 16:09
von Kobra23759
danke. jetzt geht es

Re: sleep im Unterprogramm

Verfasst: Donnerstag 23. Juni 2022, 06:36
von Kobra23759
hallo, ich habe noch eine weitere Frage
du schreibst:"Man verwendet `place()` nicht. Genau so ist `geometry()` ein Problem. Absolute Grössen- und Positionsangeben funktionieren
mit der heutigen Vielfalt an Bildschirmgrössen, -auflösungen, und -einstellungen nicht mehr."
Kannst du mir eine Alternative am Bsp geben

Re: sleep im Unterprogramm

Verfasst: Donnerstag 23. Juni 2022, 07:22
von Sirius3
@Kobra23759: die Alternative hat __blackjack__ in seinem Beispiel doch schon benutzt, sie heißt `pack`. Daneben gibt es noch `grid´, je nachdem wie man die Widgets anordnen möchte.