time.sleep() mehrfach nacheinander

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
Wawa
User
Beiträge: 4
Registriert: Montag 25. Oktober 2021, 08:12

Hallo zusammen, ich habe ein Problem mit der sleep() Methode.

Ich möchte in einem Programm ein Bild durch ein anderes ersetzen und dazwischen eine kleine Pause von einer Sekunde haben. Dies funktioniert auch ganz gut. Nun benötige ich aber fünf Bilder die von der Festplatte geladen werden und ähnlich einer Slideshow duchwechseln und jeweils eine Pause dazwischen haben sollen.
Mache ich dies mit sleep(), so unterbricht das Programm die Gesamtzeit aller 4 sleep() Einträge und wechselt dann zu Bild 5 (zumindest sieht man die Bilder 2 bis 4 nicht)

Um die sleep() Methode zu umgehen, habe ich bereits versucht, eine einfache for Schleife zu nutzen. Auch dies liefert das selbe Ergebnis.

Laut Internetsuche könnte es an irgendeinem Buffering liegen. Da bin ich jedoch raus.
Vielleicht hat jemand eine Lösung für mich?
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ohne Code kann man nur raten. Ich rate mal du benutzt tkinter, und da darf man sleep nicht benutzen. Sondern muss einen Timer nehmen. Diskutieren wir hier andauernd. Bitte im entsprechenden Unterforum nachschauen.
Wawa
User
Beiträge: 4
Registriert: Montag 25. Oktober 2021, 08:12

Zur Erklärung nochmal mein Anliegen:

Ich habe ein Programm geschrieben, welches die Bedienung eines Biathlon Schießstandes simuliert. (Gedacht als Lehrprogramm für Biathlon Kampfrichter) Dieses funktioniert auch genau so, wie ich es mir vorgestellt habe. Der Nutzer bestätigt die Ankunft des Athleten, gibt dessen Startnummer ein und bestätigt das Verlassen des Schießstandes. Hierbei wird die Schießzeit gemessen und dokumentiert. Zusätzlich hat er die Möglichkeit Fehleingaben zu korrigieren.
Ich möchte nun, um dem Ganzen etwas mehr Leben einzuhauchen, ein virtuelles Schießen einbauen. Dieses soll starten, nachdem die Startnummerneingabe bestätigt wird und durch das "Umkippen" der Zielscheiben dargestellt werden.
Ich habe also 5 PNG Bilder von Zielscheiben, die der Reihe nach angezeigt werden sollen. Natürlich soll dies in einem realistischen Zeitraum passieren, sprich mit ca. 1 oder 2 Sekunden Abstand zwischen den Bilderwechseln.

Bei mir pausiert das Programm aber nach Betätigen des entsprechenden Buttons nicht eine Sekunde sondern 5 - 6 Sekunden. Dann zeigt es gleich das letzte Bild an.

Ich habe bereits versucht, das time.sleep() duch eine Schleife zu ersetzen. Das Ergebnis ist jedoch das Gleiche.

Hier meine Imports und das entsprechende Codefragment:

import datetime
import sys
import winsound
from PyQt5 import QtWidgets, uic
import time

...
...

def ani9(self):
self.pause(1)
self.Lbl5Scheiben9.setStyleSheet("background-color: rgba(255, 0, 0,0); background-image:url(./Pad/ani1/4.png)")
self.LblHits9.setText("1")
self.pause(2)
self.Lbl5Scheiben9.setStyleSheet("background-color: rgba(255, 0, 0,0); background-image:url(./Pad/ani1/3.png)")
self.LblHits9.setText("2")
self.pause(1)
self.Lbl5Scheiben9.setStyleSheet("background-color: rgba(255, 0, 0,0); background-image:url(./Pad/ani1/2.png)")
self.LblHits9.setText("3")
self.pause(1)
self.Lbl5Scheiben9.setStyleSheet("background-color: rgba(255, 0, 0,0); background-image:url(./Pad/ani1/1.png)")
self.LblHits9.setText("4")
self.pause(2)
self.Lbl5Scheiben9.setStyleSheet("background-color: rgba(255, 0, 0,0); background-image:url(./Pad/ani1/0.png)")
self.LblHits9.setText("5")

def pause(self, t):
time.sleep(t)
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Antwort ist die gleiche. In GUIs kann man nicht warten, die sind Ereignis-basiert. Warten bedeutet nur frieren.

In Qt musst du mit QTimer arbeiten, um im Sekundentakt die GUI zu Updaten. Auch dazu wurde hier schon diskutiert & es gibt natürlich auch Beispiele in der offiziellen Dokumentation.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

@Wawa: Um das Ganze etwas zu konkretisieren: Ein GUI-Framwork läuft in einer Endlosschleife. Diese Endlosschleife sorgt dafür, dass die Oberfläche gezeichnet wird. Wenn du diese Schleife "anhälst" (und das tust du hier) friert das Programm ein. Unter Windows kennst du bestimmt das berühmte "Das Programm reagiert nicht mehr".

Deshalb hat darfst du weder die Schleife der GUI anhalten noch eine lang dauernde Operation ausführen (was das selbe Ergebnis herbeiführen würde).

Du musst dich also von dem Gedanken verabschieden, dass GUI-Programmierung rein sequentiell funktioniert. Das tut sie nicht. Sie reagiert, wie __deets__ geschrieben hat, auf Ereignisse.

Jedes GUI-Framework hat eigene Mechanismen zeitgesteuert so ein "Event" zu erzeugen. Die entsprechenden Stichwörter hat __deets__ dir ebenfalls gesagt.

GUI-Programmierung ist selten trivial. Du wirst dich ein bisschen damit beschäftigen müsssen.
Wawa
User
Beiträge: 4
Registriert: Montag 25. Oktober 2021, 08:12

Hallo _deets_ und sparrow, nun verstehe ich zumindest schon einmal, warum meine Herangehensweise nicht funktioniert. Wie der Qt-Timer funktioniert, bekomme ich bestimmt noch raus. Also vielen Dank euch Beiden.
Antworten