Seite 1 von 1
Canvas Event
Verfasst: Sonntag 5. April 2009, 21:25
von Pascal
mit ~~ canvas.tag_bind(name, '<Enter>', prozedur) ~~ kann ich ja die prozedur aufrufen, sobald ich mit der Maus auf 'name' komme.
aber das darf genau nur einmal passieren!
wenn ich ein zweites mal darauf komme soll eine andere Prozedur aufgerufen werden.
momentan habe ich dazu gar keine Idee
Bitte helft mir
Edit: Neue Frage dazu:
http://www.python-forum.de/post-143238.html#143238
Verfasst: Sonntag 5. April 2009, 21:35
von Birne94
unbind aufrufen und dann neu binden...
Verfasst: Sonntag 5. April 2009, 21:40
von Pascal

ich bin noch neuling was das programmieren angeht.
deswegen weiß ich nicht genau wie das gehen sollte
trotzdem danke für deine antwort, ein bisschen näher beschreiben wär noch gut
Danke
Verfasst: Montag 6. April 2009, 07:07
von wuf
Hallo Pascal
Hier etwas zum ausprobieren:
Code: Alles auswählen
# Skriptname: canvas_tag_unbind_01_01.py (wuf)
import Tkinter as tk
def square_first_function(event):
print 'Erste Funktion'
#~~ Loese die erste Funktion vom Canvas Rechteck-Objekt
canvas.unbind('rechteck')
#~~ Binde die zweite Funktion an das Canvas Rechteck-Objekt
canvas.tag_bind('rechteck', '<Enter>', square_second_function)
def square_second_function(event):
print 'Zweite Funktion'
app_win = tk.Tk()
canvas = tk.Canvas(app_win, width=200, height=200)
canvas.pack()
square = canvas.create_rectangle(20, 20, 100, 100, fill='steelblue',
tags='rechteck')
#~~ Binde die erste Funktion an das Canvas Rechteck-Objekt
canvas.tag_bind('rechteck', '<Enter>', square_first_function)
app_win.mainloop()
Gruss wuf

Verfasst: Montag 6. April 2009, 08:48
von Pascal
Vielen Dank!!
Das hilft mir weiter

Verfasst: Dienstag 7. April 2009, 13:19
von yipyip
Hallo Pascal,
wenn Du etwas von Deinem Quellcode zeigen würdest,
könnte man auch etwas gezielter antworten,
aber ich behaupte mal, dass das 'unbind()' nicht
die Lösung Deines Problems darstellt, sondern eher
eine bessere Organisation deines Programmes.
Deine Quadrate wollen anscheinend Identität,
Zustand und Methoden haben, also mache doch eine
Klasse daraus.
Als Beispiel hier ein kleines OO-Konzept:
http://paste.pocoo.org/show/111439/
Bei einem Enter-Event für ein Rechteck wird immer
abwechselnd entweder eine neues zufällig erzeugt
oder das aktuelle neu eingefärbt.
Vielleicht bringt Dich das Beispiel ja etwas weiter.
yipyip
Verfasst: Sonntag 12. April 2009, 18:23
von yipyip
Da ich nun endlich Deine Aufgabenstellung kenne,
hier nochmal ein 'Proof of Concept' meiner obigen Behauptung.
http://paste.pocoo.org/show/112242/
Mauszeiger auf Rechteck startet einen Countdown,
ist dieser abgelaufen, wird ein neues Rechteck erzeugt,
Mauszeiger auf dieses Rechteck startet Countdown, ist dieser ...
Selbstverständlich wird auch die Reaktionszeit zwischen
altem und neuem Rechteck berechnet.
Jaaa, ich weiss, das ist alles etwas kompliziert
(...jedenfalls fand ich die Aufgabe überhaupt nicht trivial...),
aber vielleicht kannst Du mit der Zeit ja doch noch etwas damit
anfangen.
yipyip
Verfasst: Donnerstag 30. Juli 2009, 20:08
von Pascal
Ich will diesen Thread mal nutzen, um eine weitere Frage loszuwerden:
Was muss ich tun, wenn ich mit einer for-Schleife mehrere Objekte auf einem Canvas erzeuge und diese dann an verschiedene Funktionen binden will?
Hier ein Bsp.:
Code: Alles auswählen
import Tkinter as tk
def kreis_enter1(e):
print 'Maus im Kreis'
print '1'
canv.itemconfig(k, fill='red')
def kreis_enter2(e):
print 'Maus im Kreis'
print '2'
canv.itemconfig(i, fill='red')
win=tk.Tk()
canv=tk.Canvas(win, width=500, height=500, bg='white')
canv.pack(padx=10, pady=10)
kreise=[]
###erstellen der kreise
for e in range(420,20, -50):
for i in range(70, 470, 50):
k=canv.create_oval(i+10, e+10, i-10, e-10, fill='white', outline='grey', \
tag='kreis')
kreise.append(k)
# variante 1
canv.tag_bind(k, '<Enter>', kreis_enter1)
###variante 2
##for i in kreise:
## canv.tag_bind(i, '<Enter>', kreis_enter2)
##
win.mainloop()
Ich wüsste gern, wie es geht, dass bei der Funktion der Kreis, den man "entert", konfiguriert wird.
Verfasst: Donnerstag 30. Juli 2009, 20:24
von EyDu
Wenn du ein komplett neues Thema beginnst, dann solltest du auch einen neuen Thread starten.
Du suchst wohl "functools.partial":
Code: Alles auswählen
from functools import partial
def kreis_enter(e, kreis_id):
print 'Maus im Kreis'
print kreis_id
canv.itemconfig(k, fill='red')
for i in kreise:
canv.tag_bind(i, '<Enter>', partial(kreis_enter, i))
Mal abgesehen davon, dass dein Beispiel nicht funktioniert, da "k" in den Funktionen nicht bekannt ist. Das kannst du aber, genau wie "kreis_id", einbauen.
Verfasst: Donnerstag 30. Juli 2009, 20:58
von Pascal
EyDu hat geschrieben:
Du suchst wohl "functools.partial":

genau damit habe ich es auch probiert, jedoch ohne Erfolg (Exception wurde ausgelöst)
Ich habe deine Lösung noch etwas geändert, und jetzt geht alles wunderbar.
das sieht jetzt so aus:
Code: Alles auswählen
def kreis_enter(kreis, xy_parameter):
print 'Maus im Kreis'
print kreis
canv.itemconfig(kreis, fill='red')
Code: Alles auswählen
for i in kreise:
canv.tag_bind(i, '<Enter>', partial(kreis_enter, i))
Wenn ich
xy_parameterweg lasse, kommt:
Code: Alles auswählen
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python26\lib\lib-tk\Tkinter.py", line 1410, in __call__
return self.func(*args)
TypeError: kreis_enter() takes exactly 1 argument (2 given)
Wie ist das zu verstehen?
Verfasst: Donnerstag 30. Juli 2009, 21:08
von EyDu
Hab mich verschrieben. Entweder so:
Code: Alles auswählen
def kreis_enter(kreis_id, e):
print 'Maus im Kreis'
print kreis_id
canv.itemconfig(k, fill='red')
for i in kreise:
canv.tag_bind(i, '<Enter>', partial(kreis_enter, i))
oder so:
Code: Alles auswählen
def kreis_enter(e, kreis_id):
print 'Maus im Kreis'
print kreis_id
canv.itemconfig(k, fill='red')
for i in kreise:
canv.tag_bind(i, '<Enter>', partial(kreis_enter, kreis_id=i))
sollte es gehen.
Die Fehlermeldung, welche du bekommst, sagt doch eigentlich alles: Die Funktion erwartet einen Parameter, es werden aber zwei übergeben. Die zwei Parameter ergeben sich einmal aus dem Kreis, welchen du bei partial angibst, und dann noch durch den event (das, was du mit "e" abkürzt).