2010-05-28 22 views
4

Le problème que je rencontre ici est que, lorsque je clique sur les différents noms de fichiers dans le Listbox, le Label change de valeur un clic derrière ce que je clique actuellement sur.Tkinter Label lié à StringVar est un clic derrière lors de la mise à jour

Qu'est-ce qui me manque ici?

import Tkinter as tk 

class TkTest: 

    def __init__(self, master): 

     self.fraMain = tk.Frame(master) 
     self.fraMain.pack() 

     # Set up a list box containing all the paths to choose from 
     self.lstPaths = tk.Listbox(self.fraMain) 
     paths = [ 
      '/path/file1', 
      '/path/file2', 
      '/path/file3', 
     ] 
     for path in paths: 
      self.lstPaths.insert(tk.END, path) 
     self.lstPaths.bind('<Button-1>', self.update_label) 
     self.lstPaths.pack() 

     self.currentpath = tk.StringVar() 
     self.lblCurrentPath = tk.Label(self.fraMain, textvariable=self.currentpath) 
     self.lblCurrentPath.pack() 

    def update_label(self, event): 
     print self.lstPaths.get(tk.ACTIVE), 
     print self.lstPaths.curselection() 
     self.currentpath.set(self.lstPaths.get(tk.ACTIVE)) 

root = tk.Tk() 
app = TkTest(root) 
root.mainloop() 

Répondre

4

Le problème est lié à la conception fondamentale de Tk. La version courte est, les liaisons sur des widgets spécifiques tirent avant les liaisons de classe par défaut pour un widget. C'est dans les bindings de classe que la sélection d'une listbox est modifiée. C'est exactement ce que vous observez - vous voyez la sélection avant le clic actuel.

La meilleure solution consiste à lier à l'événement virtuel <<ListboxSelect>> qui est déclenché après que la sélection a été modifiée. D'autres solutions (uniques à Tk et qui lui confèrent une puissance et une flexibilité incroyables) consistent à modifier l'ordre dans lequel les fixations sont appliquées. Cela implique de déplacer le widget bindtag après la classe bindtag, ou d'ajouter un nouveau bindtag après le bindtag de la classe et de le lier à cela.

Depuis la liaison à <<ListboxSelect>> est la meilleure solution je ne vais pas entrer dans les détails sur la façon de modifier les bindtags, même si elle est simple et je pense que assez bien documenté.

+0

Cela a fait l'affaire, merci! Je n'ai vu aucune référence à «ListboxSelect» dans les didacticiels que j'ai suivis, et même chercher Google pour ce mot ne semble pas donner beaucoup d'informations. Y a-t-il une liste de tous les événements virtuels? Cela ressemble vraiment à un «getcha» ennuyeux dans Tk ... – Sam

+1

@Sam: Il n'y a pas une seule liste de tous les événements. Les pages de manuel Tk répertorient les événements de chaque widget sur la page de manuel de ce widget. Ainsi, par exemple, << ListboxSelect >> est listé sur la page de manuel de la listbox ici: http://tcl.tk/man/tcl8.4/TkCmd/listbox.htm –