Hallo,
ich habe eine Frage:
Wie kann ich zählen wie oft ein Button gedrückt wurde?
Insgesamt soll beim ersten klicken meines Buttons eine Animation gestartet werden und beim zweiten klicken diese Animation wieder beendet werden.Und wenn man dann nochmal klickt, dann soll die Animation wieder starten usw.
Vielen Dank schonmal.
LG Joa
Button-Klicks zählen
-
BlackJack
@Joa: Wo genau liegt denn das Problem? Objektorientierte Programmierung kannst Du schon? Falls nein, solltest Du Dich damit vielleicht erst einmal unabhängig von GUI-Programmierung auseinander setzen. Dann kannst Du die Klicks einfach in einem Attribut mit zählen.
Für GUI-Fragen gibt es übrigens auch Unterforen. Das beantwortet dann in der Regel auch die Frage welches GUI-Toolkit Du verwendest.
Für GUI-Fragen gibt es übrigens auch Unterforen. Das beantwortet dann in der Regel auch die Frage welches GUI-Toolkit Du verwendest.
@Joa:
Wobei ich das Wechseln zwischen On/Off nicht über einen Zähler lösen würde. Ich würde eine Weiche einbauen, die die Animation startet, wenn diese noch nicht gestartet ist oder eben beendet, wenn sie bereits läuft.Und das 'Buttonwurdegeklickt'-Event bindest Du an 'switch()'.
Natürlich kannst Du Dir 'switch()' auch sparen und das 'started'-Flag direkt in der Animationsroutine abfragen. Hängt halt davon ab, wie Dein Programm strukturiert ist. Mein Beispiel sollte nur grundsätzlich zeigen, wie man sowas lösen kann.
mutetella
Wobei ich das Wechseln zwischen On/Off nicht über einen Zähler lösen würde. Ich würde eine Weiche einbauen, die die Animation startet, wenn diese noch nicht gestartet ist oder eben beendet, wenn sie bereits läuft.
Code: Alles auswählen
startet = False
def switch():
if started:
stop_ani()
else:
start_ani()
def start_ani():
started = True
...
def stop_ani():
started = False
...Natürlich kannst Du Dir 'switch()' auch sparen und das 'started'-Flag direkt in der Animationsroutine abfragen. Hängt halt davon ab, wie Dein Programm strukturiert ist. Mein Beispiel sollte nur grundsätzlich zeigen, wie man sowas lösen kann.
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit
)
- pillmuncher
- User
- Beiträge: 1532
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Oder als kleine State Machine mit zwei Zuständen:
Code: Alles auswählen
class Switch(object):
def __init__(self, when_on, when_off):
self._state = 0
self._transition = ((1, when_on), (0, when_off))
def __call__(self):
self._state, action = self._transition[self._state]
action()
def start_ani():
print 'an'
def stop_ani():
print 'aus'
switch = Switch(when_on=start_ani, when_off=stop_ani)
switch()
switch()
switch()
switch()
switch()In specifications, Murphy's Law supersedes Ohm's.
Cool, das gefällt mir....!! Kann ich gerade in meiner 'PatternFactory' gut gebrauchen um in ein searchpattern Suchwerte rein- oder rauszunehmen, je nachdem eben...
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit
)
Du solltest dazu sagen, dass du den Code von pillmuncher meinst, denn der von mutetella funktioniert eben ja gerade nicht (auch dann nicht, wenn man startet in started umbenennt).Joa hat geschrieben:Vielen Dank, hat super funktioniert
Stimmt...
Mein Beispiel ist echt für den Müll, selbst wenn man sich verrenkt und 'started' durchreicht...
mutetella
Mein Beispiel ist echt für den Müll, selbst wenn man sich verrenkt und 'started' durchreicht...
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit
)
-
BlackJack
@Joa: Falls ”angepasst” bedeutet, dass Du ``global`` verwendet hast, dann solltest Du eine andere Lösung suchen/nehmen. Kommunikation über globale Variablen ist unsauber.
@Joa:
Dass mein Beispiel bei Dir funktioniert muss an Deiner Anpassung liegen
!
Auf numerix' Beitrag hin konnte ich natürlich nicht mehr ruhig sitzen und musste mein Beispiel nochmal durchkauen.
Auch wenn es vorerst so aussieht, als würde es funktionieren, tauchen ganz ganz fiese Gemeinheiten auf:
- Nach dem ersten Aufruf von 'switch()' funktioniert alles, nachdem 'started' auf False zeigt wird 'start_ani()' aufgerufen.
- Innerhalb von 'start_ani()' wird 'started' auf True gesetzt, ein erneuter Aufruf von 'switch()' sollte demnach 'stop_ani()' starten. Passiert aber nicht!
- Ich ziehe also meine Wunderwaffe 'print' aus dem Ärmel
und füge gleich als erste Zeile ein 'print started' sowohl in 'switch()' als auch in 'start_ani()' ein.
- Genau jetzt beginnt mein Leidensweg: Ich rufe 'switch()' auf und erhalte Wie kann das sein
? Weshalb funktioniert 'print started' in 'switch()', wirft aber in 'start_ani()' einen 'UnboundLocalError'?
'switch()' sucht zuerst im lokalen Namensraum nach 'started' und findet dort den Namen nicht. Deshalb schaut es im globalen Namensraum (auf Modulebene) nach, findet dort den (globalen) Namen 'started', gibt 'False' aus und verzweigt zu 'start_ani()'.
Warum meckert 'start_ani()', dass es den lokalen Namen 'started' nicht findet? 'switch()' hat doch nach dem lokalen auch im globalen Namensraum gesucht?
Es muss wohl daran liegen, dass der Interpreter durch die Anweisung 'started = True' innerhalb von 'start_ani()' einen lokalen Namen 'started' anlegt. Wenn dann während der Ausführung von 'start_ani()' die print-Anweisung 'started' ausgeben möchte, wird wohl der (lokale) Name gefunden, allerdings ist dieser Name noch 'zeigerlos', da ein Verweis erst eine Zeile danach stattfindet.
Fazit: Das Problem an meinem Beispiel ist also, dass 'switch()' auf den globalen Namen 'started' (False) zugreift, 'start_ani()' und 'stop_ani()' aber jeweils ihren eigenen lokalen Namen 'started' setzen und auch gleich danach wieder verlieren, da Funktionen nach ihrem Ende ihre lokalen Namen nicht behalten.
Letztlich verwendet mein Beispiel also 3 Namen 'started', die miteinander in keiner Verbindung stehen, obwohl sie den selben Namen tragen.
Sauber wäre also folgendes:
mutetella
Dass mein Beispiel bei Dir funktioniert muss an Deiner Anpassung liegen
Auf numerix' Beitrag hin konnte ich natürlich nicht mehr ruhig sitzen und musste mein Beispiel nochmal durchkauen.
Auch wenn es vorerst so aussieht, als würde es funktionieren, tauchen ganz ganz fiese Gemeinheiten auf:
- Nach dem ersten Aufruf von 'switch()' funktioniert alles, nachdem 'started' auf False zeigt wird 'start_ani()' aufgerufen.
- Innerhalb von 'start_ani()' wird 'started' auf True gesetzt, ein erneuter Aufruf von 'switch()' sollte demnach 'stop_ani()' starten. Passiert aber nicht!
- Ich ziehe also meine Wunderwaffe 'print' aus dem Ärmel
Code: Alles auswählen
started = False
def switch():
print started
if started:
stop_ani()
else:
start_ani()
def start_ani():
print started
started = True
print 'gestartet'
def stop_ani():
started = False
print 'gestoppt'Code: Alles auswählen
In [62]: switch()
False
-------------------------------------------------------
10 def start_ani():
---> 11 print started
12 started = True
13 print 'gestartet'
UnboundLocalError: local variable 'started' referenced before assignment'switch()' sucht zuerst im lokalen Namensraum nach 'started' und findet dort den Namen nicht. Deshalb schaut es im globalen Namensraum (auf Modulebene) nach, findet dort den (globalen) Namen 'started', gibt 'False' aus und verzweigt zu 'start_ani()'.
Warum meckert 'start_ani()', dass es den lokalen Namen 'started' nicht findet? 'switch()' hat doch nach dem lokalen auch im globalen Namensraum gesucht?
Es muss wohl daran liegen, dass der Interpreter durch die Anweisung 'started = True' innerhalb von 'start_ani()' einen lokalen Namen 'started' anlegt. Wenn dann während der Ausführung von 'start_ani()' die print-Anweisung 'started' ausgeben möchte, wird wohl der (lokale) Name gefunden, allerdings ist dieser Name noch 'zeigerlos', da ein Verweis erst eine Zeile danach stattfindet.
Fazit: Das Problem an meinem Beispiel ist also, dass 'switch()' auf den globalen Namen 'started' (False) zugreift, 'start_ani()' und 'stop_ani()' aber jeweils ihren eigenen lokalen Namen 'started' setzen und auch gleich danach wieder verlieren, da Funktionen nach ihrem Ende ihre lokalen Namen nicht behalten.
Letztlich verwendet mein Beispiel also 3 Namen 'started', die miteinander in keiner Verbindung stehen, obwohl sie den selben Namen tragen.
Sauber wäre also folgendes:
Code: Alles auswählen
def switch(started):
if started:
started = stop_ani()
else:
started = start_ani()
return started
def start_ani():
print 'gestartet'
return True
def stop_ani():
print 'gestoppt'
return False
In [67]: started = False
In [68]: started = switch(started)
gestartet
In [69]: started = switch(started)
gestoppt
In [70]: started = switch(started)
gestartetmutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit
)
Überhaupt nichts. Hatte ich doch bereits gesagt, dass ich pillmuncher's Lösung sehr viel besser finde!snafu hat geschrieben:Was hast du gegen die bereits vorgeschlagene Verwendung einer Klasse auszusetzen?
Nachdem aber Joa schreibt, dass er meine Variante verwendet (wenn auch 'angepasst') wollte ich mein nicht funktionierendes Beispiel noch in einer 'sauberen', will heißen funktionierenden 'globalfreien' Version einstellen.
Mein ganzes Geschreibe drumherum sollte nicht für meine Variante 'werben' sondern nur aufzeigen, in welche Fallen man (ich!) mit globalen Variablen immer wieder tappen kann.
Ursprünglich war mein Beispiel auch nicht zur Weiterverwendung gedacht. Ich wollte damit nur zeigen, dass sich die Verwendung eines start-/stop-flag gegenüber einem Zähler IMHO besser eignet.
mutetella
EDIT: Letztlich würde mich jetzt a bisl interessieren, wie Joa's Lösung wohl aussieht...
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit
)
