TreeView.focus() liefert falsches Element

Fragen zu Tkinter.
Antworten
sedi
User
Beiträge: 104
Registriert: Sonntag 9. Dezember 2007, 19:22

Hallo ich habe versucht ein TreeView zur Darstellung von Verzeichnissen zu benutzen.

In der Dokumentation vom NMT (http://infohost.nmt.edu/tcc/help/pubs/t ... eview.html) wird erwähnt, dass man das momentan selektierte Element mit der Abfrage

Code: Alles auswählen

iid = treeviewobject.focus()
erhält! Bei meinem Beispiel funktioniert das aber nicht - man muss 2x auf das Element klicken, damit die richtige ausgewählt wird.

Wie schaff' ich es, das tatsächlich die richtige und nicht die vorherige iid zurückgegeben wird?

Hier mal mein Code für Euch:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-


"""
heavily inspired by:
http://stackoverflow.com/questions/16746387/tkinter-treeview-widget
"""


import os
import Tkinter as tk
import ttk


class DirectoryBrowser(tk.Frame):
    def __init__(self, master, path):
        self.path = os.path.abspath(path)
        self.entries = {"": self.path}
        self.root = None

        # setup treeview and scrollbars
        
        tk.Frame.__init__(self, master)
        self.tree = ttk.Treeview(self)
        
        ysb = ttk.Scrollbar(self, 
                            orient='vertical',
                            command=self.tree.yview)
        xsb = ttk.Scrollbar(self, 
                            orient='horizontal', 
                            command=self.tree.xview)
        
        self.tree.configure(yscroll=ysb.set, xscroll=xsb.set)
        self.tree.heading('#0', text='Path', anchor='w')
        self.tree.bind("<Button-1>", self.update_subtree)
        
        # fill treeview with root dir and the subdirs
        
        iid = self.insert("", "end", self.path)
        self.tree.focus(iid)
        self.process_directory(iid, self.path)
        
        # add tree and scrollbars to frame
        
        self.tree.grid(in_=self, row=0, column=0, sticky="nsew")
        ysb.grid(in_=self, row=0, column=1, sticky="ns")
        xsb.grid(in_=self, row=1, column=0, sticky="ew")
        
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        
        self.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.Y)

    def insert(self, parent, index, path, name="", **kwargs):
        """Neues Element dem TreeView hinzufuegen.
        """
        if "text" in kwargs:
            err = "arg 'text' not available"
            raise ValueError(err)
        
        kwargs["text"] = path
        if name:
            kwargs["text"] = name
        
        iid = self.tree.insert(parent, index, **kwargs)
        self.entries[iid] = path
        return iid
    
    def process_directory(self, parent, path, depth=3):
        if depth == 0:
            return
        
        for p in os.listdir(path):
            abspath = os.path.join(path, p)
            if os.path.isdir(abspath):
                iid = self.insert(parent,
                                  'end', 
                                  path=abspath,
                                  name=p,
                                  open=False)
                self.process_directory(iid, abspath, depth-1)

    # Callbacks
    
    def update_subtree(self, event):
        iid = self.tree.focus()
        path = self.entries[iid]
        
        # FIXME: falsche iid bei einfachem Klick

        print "%s: %s" % (iid, path)
        print iid in self.entries.keys()
        #self.process_directory(iid, path)


def test():
    root = tk.Tk()
    verzeichnis = "~/Dokumente" # ...
    app = DirectoryBrowser(root, path=verzeichnis)
    app.mainloop()


if __name__ == "__main__":
    test()
CU sedi
----------------------------------------------------------
Python 3.5; Python 3.6
LinuxMint18
sedi
User
Beiträge: 104
Registriert: Sonntag 9. Dezember 2007, 19:22

Ok - habe das Problem selbst gelöst - nachdem ich nochmals recherchiert habe :(

Man muss den "virtuellen Event"

Code: Alles auswählen

self.tree.bind("<<TreeviewSelect>>", self.update_subtree)
benutzen anstatt

Code: Alles auswählen

self.tree.bind("<Button-1>", self.update_subtree)
Sorry - für die Umstände...
CU sedi
----------------------------------------------------------
Python 3.5; Python 3.6
LinuxMint18
Ene Uran
User
Beiträge: 125
Registriert: Sonntag 17. September 2006, 20:14
Wohnort: Hollywood

Vielen Dank fuer die Loesung.
Atomkraftwerkaktienbesitzer
Antworten