Seite 1 von 1
for event schleife
Verfasst: Donnerstag 1. April 2021, 13:38
von G-Rizzle
Hallo,
ich bin dabei ein etwas komplexeres Programm zu schreiben, mit dem ich eine Tello Drohne steuern will.
Meine Idee ist folgende:
ich habe mein main Programm, in dem ich die ganzen Unterfunktionen aus anderen Skripts aus diesem Ordner aufrufe. Das mache ich aus Übersichtlichkeitsgründen. Im main gibt es damit nur die main() Funktion, in der erst einige Werte initialisiert werden und dann die while-Schleife betreten wird. Zunächst werden die Funktiionen aufgerufen, dann zum Schluss die
Code: Alles auswählen
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
Ausdrücke.
Nun möchte ich eine Fotoabspeicherfunktion implementieren. Das Bildmachen an sich ist kein Problem, nur möchte ich, dass nach Bildschuss eine Textbox erscheint, in die der Nutzer den Namen des BIldes eintragen kann. In diesem Zustand ist die Variable steuerung_aktive == Falsch.
Daran scheitere ich.
Ich nutze als Hilfe
https://www.youtube.com/watch?v=Rvcyf4HsWiw&t=519s , sowie
https://www.codegrepper.com/code-exampl ... hon+pygame
meine Klasse textBox sieht so aus:
Code: Alles auswählen
class textBox():
def __init__(self, x, y, breite, hoehe, buttonfarbe, text_input, textfarbe, schriftgroesse):
self.x = x
self.y = y
self.breite = breite
self.hoehe = hoehe
self.buttonfarbe = buttonfarbe
self.text_input = text_input
self.textfarbe = textfarbe
self.schriftgroesse = schriftgroesse
def zeichne_button(self, SCREEN, event):
rechteckiger_button = Rect(self.x, self.y, self.breite, self.hoehe)
if event.type == pygame.KEYDOWN:
if steuerung.ist_taste_gedrueckt("BACKSPACE"):
self.text_input = self.text_input[:-1]
else:
self.text_input += event.unicode
pygame.draw.rect(SCREEN, self.buttonfarbe, rechteckiger_button)
text_als_button = self.schriftgroesse.render(self.text_input, True, self.textfarbe)
#text_laenge = text_als_button.get_width()
SCREEN.blit(text_als_button, (self.x, self.y))
ich baue zeichne_button folgend ein:
Code: Alles auswählen
# Fensterevents
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if steuerung_aktiv == False:
button_modul.text_box.zeichne_button(SCREEN, event)
an sich funktioniert es, ich sehe die Box im Fenster und ich kann Text eintippen, ich sehe die Box jedoch nur wenn ich meine Maus bewege oder schreibe für den Bruchteil einer Sekunde. Danach ist sie sofort wieder weg und ich sehe das leere pygame Fenster. Wo ist hier mein Fehler? Wie könnte ich es besser machen?
Danke!
Re: for event schleife
Verfasst: Donnerstag 1. April 2021, 13:39
von G-Rizzle
G-Rizzle hat geschrieben: Donnerstag 1. April 2021, 13:38
Hallo,
ich bin dabei ein etwas komplexeres Programm zu schreiben, mit dem ich eine Tello Drohne steuern will.
Meine Idee ist folgende:
ich habe mein main Programm, in dem ich die ganzen Unterfunktionen aus anderen Skripts aus diesem Ordner aufrufe. Das mache ich aus Übersichtlichkeitsgründen. Im main gibt es damit nur die main() Funktion, in der erst einige Werte initialisiert werden und dann die while-Schleife betreten wird. Zunächst werden die Funktiionen aufgerufen, dann zum Schluss die
Code: Alles auswählen
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
Ausdrücke.
Nun möchte ich eine Fotoabspeicherfunktion implementieren. Das Bildmachen an sich ist kein Problem, nur möchte ich, dass nach Bildschuss eine Textbox erscheint, in die der Nutzer den Namen des BIldes eintragen kann. In diesem Zustand ist die Variable steuerung_aktive == Falsch.
Daran scheitere ich.
Ich nutze als Hilfe
https://www.youtube.com/watch?v=Rvcyf4HsWiw&t=519s , sowie
https://www.codegrepper.com/code-exampl ... hon+pygame
meine Klasse textBox sieht so aus:
Code: Alles auswählen
class textBox():
def __init__(self, x, y, breite, hoehe, buttonfarbe, text_input, textfarbe, schriftgroesse):
self.x = x
self.y = y
self.breite = breite
self.hoehe = hoehe
self.buttonfarbe = buttonfarbe
self.text_input = text_input
self.textfarbe = textfarbe
self.schriftgroesse = schriftgroesse
def zeichne_button(self, SCREEN, event):
rechteckiger_button = Rect(self.x, self.y, self.breite, self.hoehe)
if event.type == pygame.KEYDOWN:
if steuerung.ist_taste_gedrueckt("BACKSPACE"):
self.text_input = self.text_input[:-1]
else:
self.text_input += event.unicode
pygame.draw.rect(SCREEN, self.buttonfarbe, rechteckiger_button)
text_als_button = self.schriftgroesse.render(self.text_input, True, self.textfarbe)
#text_laenge = text_als_button.get_width()
SCREEN.blit(text_als_button, (self.x, self.y))
ich baue die Funktion zeichne_button folgend in die for event Schleife in der main() Funktion ein:
Code: Alles auswählen
# Fensterevents
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if steuerung_aktiv == False:
button_modul.text_box.zeichne_button(SCREEN, event)
an sich funktioniert es, ich sehe die Box im Fenster und ich kann Text eintippen, ich sehe die Box jedoch nur wenn ich meine Maus bewege oder schreibe für den Bruchteil einer Sekunde. Danach ist sie sofort wieder weg und ich sehe das leere pygame Fenster. Wo ist hier mein Fehler? Wie könnte ich es besser machen?
Danke!
Re: for event schleife
Verfasst: Donnerstag 1. April 2021, 14:04
von Sirius3
Klassen schreibt man mit großem Anfangsbuchstaben `TextBox` und Variablennamen schreibt man komplett klein `screen`.
Du brauchst, wie im anderen Thread ja schon gezeigt, zwei Methoden, eine zum Abarbeiten eines Events, und eine zum Zeichnen.
Code: Alles auswählen
class TextBox():
def __init__(self, x, y, breite, hoehe, buttonfarbe, text_input, textfarbe, schriftgroesse):
self.x = x
self.y = y
self.breite = breite
self.hoehe = hoehe
self.buttonfarbe = buttonfarbe
self.text_input = text_input
self.textfarbe = textfarbe
self.schriftgroesse = schriftgroesse
def process_event(self, event):
if event.type == pygame.KEYDOWN:
if steuerung.ist_taste_gedrueckt("BACKSPACE"):
self.text_input = self.text_input[:-1]
else:
self.text_input += event.unicode
def zeichne_button(self, screen):
rechteckiger_button = Rect(self.x, self.y, self.breite, self.hoehe)
pygame.draw.rect(screen, self.buttonfarbe, rechteckiger_button)
text_als_button = self.schriftgroesse.render(self.text_input, True, self.textfarbe)
screen.blit(text_als_button, (self.x, self.y))
Und entscheidend ist ja, was sonst noch in Deiner Mainloop passiert. Da übermalst Du wahrscheinlich Deine Box wieder. Den Code brauchen wir auch noch.
Re: for event schleife
Verfasst: Donnerstag 1. April 2021, 14:41
von G-Rizzle
ahhh. ich verstehe deinen post im anderen thread jetzt erst richtig. ich tüftel mal noch ne weile und melde mich ggfs. nochmal. danke!
Re: for event schleife
Verfasst: Freitag 2. April 2021, 14:54
von G-Rizzle
okay, leider immnoch selbiges Problem. Klasse TextBox habe ich entsprechend angepasst. Zur "variable" screen: Dachte das wäre eine Konstante? Wird ja im Ursprung initialisiert und dann nicht mehr verändert? Verändere ich dann auf jeden Fall noch ggfs. nach deiner Antwort.
hier mein Mainloop: Kurze Erklärung: Die Drohne hat 3 Zustände, disconnected, connecting, connected. Das wird über die Variable "connected" festgehalten.
Zustand 1, disconnected: Variable connected == "disconnected". Im Fenster erscheinen die Buttons "disconnected", daneben ein interaktiver "connect" button, der bei klick entsprechende Drohnenverbindung versucht und Variable connected in "connecting" verändert. klappt das nicht springt die connect Variable wieder in den "disconnected" Zustand, ansonsten wird sie zu "connected".
Code: Alles auswählen
# Schleifeninitialierung
run = True
durchlauf = 0
# Schleife
while run:
# --- Fensteraufbau ---
# Hintergrund
SCREEN.fill(farben.dunkelblau2)
button_modul.oberer_balken.zeichne_button(SCREEN)
# Disconnected
if connected == 'disconnected':
# statischer disconnected Button
button_modul.disconnected_button.zeichne_button(SCREEN)
# interaktiver 'verbinden' button
button_modul.direktverbinden_button.zeichne_button(SCREEN, button_modul.direktverbinden_button.geklickt, button_modul.direktverbinden_button.action)
# Wenn 'Verbinden' Button geklickt wird
if button_modul.direktverbinden_button.action == True:
connected = 'connecting'
button_modul.direktverbinden_button.action = False
# Verbindung aktiviert
elif connected == 'connecting':
# statischer 'Verbinden...' Button
button_modul.verbinden_button.zeichne_button(SCREEN)
if zum_ersten_mal_verbinden == True:
zum_ersten_mal_verbinden = False
else:
verbinden_return = dronen_funktionen.verbinden(drone)
zum_ersten_mal_verbinden = True
if verbinden_return == True:
connected = 'connected'
else:
connected = 'disconnected'
# Verbunden, Direkt
elif connected == 'connected':
#steuerung_aktiv = True
# connected-button zeichnen
button_modul.direktverbunden_button.zeichne_button(SCREEN)
# alle 1000 Durchläufe:
# Verbindungscheck
if durchlauf == 0:
connected = dronen_funktionen.verbindung_checken(drone)
# Batterieanzeige
batterieanzeige_return = dronen_funktionen.batterie_checken(drone)
batteriebutton = batterieanzeige_return['batteriebutton']
batteriebutton.zeichne_button(SCREEN)
# Videostream
videostreamen_return = dronen_funktionen.videostreamen(drone)
SCREEN.blit(videostreamen_return['surfed_stream'], (initialisieren_return['FENSTER_BREITE'] / 2 - videostreamen_return['STREAM_BREITE'] / 2 , 30))
# steuerung
steuern_return = steuerung.steuern(drone, steuern_return['drueckzeiten'], steuern_return['sekundenzaehler'])
# Fensterevents
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
button_modul.text_box.process_event(event)
button_modul.text_box.zeichne_button(SCREEN)
# --- Update ---
# Zählvariable
durchlauf += 1
if durchlauf == 1000:
durchlauf = 0
else:
pass
# Refresh
pygame.display.update()
wie gesagt, an sich erscheint die Textbox, allerdings nur für den Bruchteil einer Sekunde falls sich irgendwas im Fenster ändert (z.b. wenn ich tippe oder maus bewege).
Re: for event schleife
Verfasst: Samstag 3. April 2021, 13:12
von __blackjack__
@G-Rizzle: Screen ist keine Konstante. Das ist ein Objekt mit Zustand der vom Programm geändert wird.
Die Aufteilung auf Module sieht auch so aus als wäre da noch mehr globaler Zustand. Was da so im `button_modul` ist sollte da nicht einfach so auf Modulebene vorhanden sein. Das ist auch ein bisschen schräg ausgerechnet alle Buttons in ein Modul zu stecken. Das ist so als würde eine Bibliothek die Bücher nach Grösse und Einbandfarben ordnen statt nach Fachrichtung und alphabetisch.
Dann hängt man nicht einen `_return`-Suffix an Namen nur weil die an einen Rückgabewert von einem Aufruf gebunden werden. Was soll das denn? Das ist doch völlig egal ob so ein Wert aus einem Literal, einem Operator, oder einem Aufruf stammt.
Es gibt da anscheinend auch Rückgabewerte die Wörterbücher sind die offenbar als Objekte herhalten. Da sollte man Objekte verwenden, beispielsweise von einem mit `collections.namedtuple()` erstellten Datentyp.
In Modulnamen sollte weder der Teil `modul` vorkommen noch `funktionen`.
Re: for event schleife
Verfasst: Samstag 3. April 2021, 14:26
von G-Rizzle
merci. setze ich gleich mal um. auf das eigentliche problem mit der verschwindenden textbox hat das allerdings keinen einfluss oder?
Re: for event schleife
Verfasst: Samstag 3. April 2021, 17:05
von G-Rizzle
ich habe die lösung: fehler war die funktion zeichne_button(screen) mit in die for event in pygame.event.get() schleife zu packen. ich habe die jetzt zu den anderen button_zeichnen() funktionen gesetzt und dann passt alles