sleep im Unterprogramm

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
Kobra23759
User
Beiträge: 61
Registriert: Donnerstag 9. April 2020, 18:47

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()
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

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
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Kobra23759
User
Beiträge: 61
Registriert: Donnerstag 9. April 2020, 18:47

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()
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Kobra23759
User
Beiträge: 61
Registriert: Donnerstag 9. April 2020, 18:47

danke. jetzt geht es
Kobra23759
User
Beiträge: 61
Registriert: Donnerstag 9. April 2020, 18:47

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
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@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.
Antworten