Turtle-Grafik in Python - letzter Aufruf wird nicht angezeigt?
Hallo Community, eine Frage:
Ich habe versucht, die grafische Simulation einer Ampel zu coden. Die Darstellung soll der Einfachkeit halber mit Turtle funktionieren. Im Grunde klappt alles wunderbar, nur die Grün-Phase wird in der Anzeige "übersprungen". Spannend: Wenn ich manuell über die passenden Methode die Grünphase einstelle, wird sie einwandfrei angezeigt. Nur in der Endlosschleife sehe ich gar nichts bzw. ein kurzes "Flackern".
Hat jemand eine Idee, woran das liegen könnten?
import turtle
import time
class Lampe():
def __init__(self, farbe, x, y):
self.__zustand = False
self.farbe = farbe
self.turtle = turtle.Turtle()
self.turtle.hideturtle()
self.turtle.penup()
self.turtle.speed(0)
self.turtle.shape("circle")
self.turtle.color(farbe)
self.turtle.goto(x, y)
def einschalten(self):
self.__zustand = True
self.turtle.color(self.farbe)
self.turtle.stamp()
def ausschalten(self):
self.__zustand = False
self.turtle.clear()
def zustand(self):
return self.__zustand
class Ampel():
def __init__(self):
self.__rot = Lampe("red", 0, 50)
self.__gelb = Lampe("yellow", 0, 0)
self.__green = Lampe("green", 0, -50)
self.__phase = "rot"
self.__rot.einschalten()
def phase_rot(self):
self.__rot.einschalten()
self.__gelb.ausschalten()
self.__green.ausschalten()
self.__phase = "rot"
def phase_gelb(self):
self.__rot.ausschalten()
self.__gelb.einschalten()
self.__green.ausschalten()
self.__phase = "gelb"
def phase_green(self):
self.__rot.ausschalten()
self.__gelb.ausschalten()
self.__green.einschalten()
self.__phase = "green"
def phase_rotgelb(self):
self.__rot.einschalten()
self.__gelb.einschalten()
self.__green.ausschalten()
self.__phase = "rotgelb"
def umschalten(self):
if self.__phase == "rot":
self.phase_rotgelb()
elif self.__phase == "rotgelb":
self.phase_green()
elif self.__phase == "green":
self.phase_gelb()
elif self.__phase == "gelb":
self.phase_rot()
else:
print("Something went horribly utterly wrong. Doomsday!")
time.sleep(2)
self.umschalten()
if __name__ == "__main__":
turtle.Screen().bgcolor("black")
ampel = Ampel()
ampel.umschalten()
2 Antworten
Eine wirkliche Erklärung, warum der Fehler so auftritt, kann ich dir leider nicht geben. Eigentlich müsste es genau andersrum sein. Also dass rot und gelb nur kurz aufblitzen, aber grün dauerhaft leuchtet.
Anscheinend zeichnet turtle die letzte Aktion erst, wenn eine weitere Turtle-Aktion stattgefunden hat. Bei Rot und Gelb schaltest du danach ja Grün aus (bzw. mit turtle.clear() löschst du eigentlich das ganze Canvas), was eine weitere Aktion ist. Bei Grün ist das einschalten aber die letzte Aktion vor dem time.sleep().
Ein paar Varianten, um das Problem beheben:
- Bei Grün noch eine Aktion nach dem Einschalten einfügen:
def phase_green(self):
self.__rot.ausschalten()
self.__gelb.ausschalten()
self.__green.einschalten()
self.__green.turtle.fd(0) # 0 Pixel vorwärts laufen
self.__phase = "green"
- Statt stamp() und clear() lieber showturtle() und hideturtle() benutzen
def einschalten(self):
self.__zustand = True
#self.turtle.color(self.farbe) # Die Farbe ist schon eingestellt
self.turtle.showturtle()
def ausschalten(self):
self.__zustand = False
self.turtle.hideturtle()
- statt time.sleep() lieber turtle.ontimer() benutzen. (Hat auch den Vorteil, dass der Rest vom Programm während der Pause noch reagiert)
def umschalten(self):
if self.__phase == "rot":
self.phase_rotgelb()
elif self.__phase == "rotgelb":
self.phase_green()
elif self.__phase == "green":
self.phase_gelb()
elif self.__phase == "gelb":
self.phase_rot()
else:
print("Something went horribly utterly wrong. Doomsday!")
turtle.ontimer(self.umschalten, 2000)
Der Code läuft ohne Pausen so schnell durch wie der Prozessor arbeitet. Du musst nach jeder Phase eine Pause setzen damit die Änderung dargestellt wird.
HI,
danke für den Tipp, aber es ist ja über time.sleep(2) eine Pause eingebaut, die übrigens bei allen anderen Ampelphasen auch einwandfrei funktioniert...