Stephan hat geschrieben:
eine Möglichkeit wäre auch, die Listbox mit einem Doppelklick abzufragen.
Hi Stephan,
ein guter Einfall. Jetzt habe ich auch erst verstanden, worauf Toni anspielte. Das Problem hatte ich damals schon in Visual Basic: es werden mehrere Reaktionen auf das Ereignis "Änderung der Auswahl" ausgeführt. Leider wird z.B. das click-Ereignis vorher an Python gemeldet, erst dann wird die Selection umgeschaltet. D.h. bei der Abfrage bekommt man immer noch den Stand vor der Selection-Änderung. Aufbauend auf Deinen Code habe ich mal zwei Möglichkeiten der Verzögerung eingebaut:
Code: Alles auswählen
import Tkinter as tk
import thread, time
def ausgabe(event = None):
if event: time.sleep(0.01)
print listbox.get('active')
root = tk.Tk()
listbox = tk.Listbox(root,height=10)
def start_after(event): listbox.after(10, ausgabe)
def start_thread(event): thread.start_new_thread(ausgabe, (event,))
listbox.bind('<ButtonRelease-1>', start_after)
#listbox.bind('<ButtonRelease-1>', start_thread)
listbox.pack()
for x in range(10):
listbox.insert(tk.END,x)
root.mainloop()
Weg 1: Methode after
In Zeile 11 wird eine Hilfsprozedur definiert, die über die Widget-Methode "after" den Eventhandler nach 10 Millisekunden aufruft. Auf diesem Wege geht leider das Eventobjekt verloren, daher ist event in der Funktion "ausgabe" optional. Es spielt in diesem Fall auch keine Rolle, aber wenn man es braucht, kann man es in der Funktion start_after in die Listbox verlinken
Weg 2: thread und time.sleep
Die Hilfsprozedur Zeile 12 wird in Zeile 14 (Raute in Z. 13 versetzen) aufgerufen und ruft den Eventhandler Z. 5 in einem neuen Thread. Hier kann das event-Objekt direkt übergeben werden, das auch gleich als Kriterium genutzt wird, ob noch einmal 10 ms gewartet werden soll.
In beiden Fällen sollten die 10 ms genügen, damit sich die Selection der Listbox ändert.
Aber wenn ein Doppelklick ok ist, finde ich Stephans Variante am elegantesten.
Grüße,
der Michel