2

I'm making a rudimentary file manager and am stuck on the question in my post's title. First it looks in a directory, generates a list of items, and appends them to the treeview list.

If a subdirectory is clicked, it becomes the new current directory. All I need is to send this back into the def where it reads and display the current directories contents (I think).

    import gtk, os

    class PyApp(gtk.Window): 
        def __init__(self):
            super(PyApp, self).__init__()
            self.set_size_request(250, 200)
            self.set_position(gtk.WIN_POS_CENTER)
            self.connect("destroy", gtk.main_quit)
            self.set_title("SteveFM")
            vbox = gtk.VBox(False, 8)
            sw = gtk.ScrolledWindow()
            sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
            sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
            vbox.pack_start(sw, True, True, 0)
            store = self.create_model()
            treeView = gtk.TreeView(store)
            treeView.connect("row-activated", self.on_activated)
            treeView.set_rules_hint(True)
            sw.add(treeView)
            self.create_columns(treeView)        
            self.add(vbox)
            self.show_all()

        #  Take the names of files and subdirectories in 
        #  the current directory and sort them into a list for treeview

        def create_model(self):
            store = gtk.ListStore(str)
            dirList=os.listdir(os.getcwd())
            dircontents = []
            for item in dirList: 
                if item[0] != '.':
                    if os.path.isdir(item):
                        dircontents.append(['/'+item])
                    else:
                        dircontents.append([item])
            dircontents.sort() 
            for act in dircontents:
                store.append([act[0]])
            return store

        #  If a file is clicked, open with leafpad.
        #  If a directory is clicked, change the current working directory to it
        #  and (my hurdle) replace the current treeview list with the contents of the 
        #  new directory, just like a file manager.

        def on_activated(self, widget, row, col):
            model = widget.get_model()
            target = model[row][0]
            if target[0] != "/":
                cmd = "leafpad "+target
                os.system(cmd)
            else:
                os.chdir(os.getcwd()+target)
                print os.getcwd()   # Just for debugging

        def create_columns(self, treeView):
            rendererText = gtk.CellRendererText()
            column = gtk.TreeViewColumn(None, rendererText, text=0)
            column.set_sort_column_id(0)    
            treeView.append_column(column)     

PyApp() 
gtk.main()
gpoo
  • 8,408
  • 3
  • 38
  • 53
Fruckubus Crunt
  • 199
  • 2
  • 16

1 Answers1

1

Changes I made:

  1. Replace treeView with self.treeView so I can access it easily in other methods.

  2. In on_activated, create a new model with create_model, and set self.treeView to use that model using gtk.TreeView.set_model.

It seems to work. Code:

import gtk, os

class PyApp(gtk.Window): 
    def __init__(self):
        super(PyApp, self).__init__()
        self.set_size_request(250, 200)
        self.set_position(gtk.WIN_POS_CENTER)
        self.connect("destroy", gtk.main_quit)
        self.set_title("SteveFM")
        vbox = gtk.VBox(False, 8)
        sw = gtk.ScrolledWindow()
        sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        vbox.pack_start(sw, True, True, 0)
        store = self.create_model()
        self.treeView = gtk.TreeView(store)
        self.treeView.connect("row-activated", self.on_activated)
        self.treeView.set_rules_hint(True)
        sw.add(self.treeView)
        self.create_columns(self.treeView)        
        self.add(vbox)
        self.show_all()

    #  Take the names of files and subdirectories in 
    #  the current directory and sort them into a list for treeview

    def create_model(self):
        store = gtk.ListStore(str)
        dirList=os.listdir(os.getcwd())
        dircontents = []
        for item in dirList: 
            if item[0] != '.':
                if os.path.isdir(item):
                    dircontents.append(['/'+item])
                else:
                    dircontents.append([item])
        dircontents.sort() 
        for act in dircontents:
            store.append([act[0]])
        return store

    #  If a file is clicked, open with leafpad.
    #  If a directory is clicked, change the current working directory to it
    #  and (my hurdle) replace the current treeview list with the contents of the 
    #  new directory, just like a file manager.

    def on_activated(self, widget, row, col):
        model = widget.get_model()
        target = model[row][0]
        if target[0] != "/":
            cmd = "leafpad "+target
            os.system(cmd)
        else:
            os.chdir(os.getcwd()+target)
            print os.getcwd()   # Just for debugging
            self.treeView.set_model(self.create_model())

    def create_columns(self, treeView):
        rendererText = gtk.CellRendererText()
        column = gtk.TreeViewColumn(None, rendererText, text=0)
        column.set_sort_column_id(0)    
        self.treeView.append_column(column)     

PyApp() 
gtk.main()
dumbmatter
  • 9,351
  • 7
  • 41
  • 80
  • 2
    You don't need to create a new model, but update the one you're using, then the GtkTreeView will update the view by itself. – erick2red Jul 30 '11 at 12:39
  • @erick2red I had read that your suggestion was the proper way, but was confused as to how to do it. Maybe Jeremy's changes with "self." in the init will allow me to troubleshoot that approach again. – Fruckubus Crunt Jul 30 '11 at 12:58
  • 2
    You'd need to make a function `update_model` that deletes everything from the current model ([`gtk.ListStore.clear`](http://www.pygtk.org/docs/pygtk/class-gtkliststore.html#method-gtkliststore--clear)) and then adds new stuff (similar to `create_model`). Then, if you really want to have fun, benchmark both methods and see what the performance difference is. – dumbmatter Jul 30 '11 at 13:01
  • Nice, I'll try it out. Re-creating the model fresh isn't showing bad performance, but a little obsession for speed is always good. – Fruckubus Crunt Jul 30 '11 at 14:01