为什么Gtk.TreeSelection.select_iter()不起作用?

时间:2014-11-08 17:52:51

标签: python gtk3 pygobject

我想实现一个允许用户通过箭头键在Gtk.TreeView小部件中导航的功能,遗憾的是select_iter()方法没有做我期待的事情,我。即它无法选择所选节点的父节点:P

现在我需要解释为什么它不起作用或暗示这个问题的某种解决方法。

以下是准备运行测试程序,它演示了这个问题。有问题的代码行用#FIXME标记。

from gi.repository import Gtk
from gi.repository import Gdk


class WizardManager(Gtk.Dialog):
    '''Dialog window which makes possible to choose type of resource to create by editor.'''
    def __init__(self, parent):
        super().__init__('Wizard manager', parent,  Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT)
        self.set_default_response(Gtk.ResponseType.OK)
        self.set_decorated(False)
        self.set_size_request(640, 480)
        vbox = self.get_content_area()
        self.__tree_store = Gtk.TreeStore(str)
        self.__tree_view = Gtk.TreeView(self.__tree_store)
        self.__tree_view.get_selection().set_mode(Gtk.SelectionMode.SINGLE)
        self.__tree_view.connect('key-press-event', self.__on_tree_view_key_press)
        self.__tree_view.set_headers_visible(False)
        text_renderer = Gtk.CellRendererText()
        text_column1 = Gtk.TreeViewColumn(None, text_renderer)
        text_column1.add_attribute(text_renderer, 'text', 0)
        self.__tree_view.append_column(text_column1)
        scrolled_window = Gtk.ScrolledWindow()
        scrolled_window.add(self.__tree_view)
        vbox.pack_start(scrolled_window, True, True, 0)
        self.__populate_tree_store()
        self.show_all()

    def __on_tree_view_key_press(self, tree_view, event):
        # TODO Implement tree navigation with arrow keys
        tree_selection = tree_view.get_selection()
        selected_iter = tree_selection.get_selected()[1]
        if selected_iter:
            selected_tree_path = self.__tree_store.get_path(selected_iter)
            # Right arrow and Return should expand selected node.
            if event.keyval == Gdk.KEY_Right or event.keyval == Gdk.KEY_Return:
                tree_view.expand_row(selected_tree_path, False)
            # Left arrow should collapse node or select it parent.
            elif event.keyval == Gdk.KEY_Left:
                if not tree_view.collapse_row(selected_tree_path):
                    # Unable to collapse node it must be empty. select it's parent.
                    parent_iter = selected_iter.copy()
                    if self.__tree_store.iter_parent(parent_iter):
                        # FIXME Why select_iter() executes without error and is not able to select parent node?
                        # same goes for select_path() :P
                        tree_selection.select_iter(parent_iter)

    def __populate_tree_store(self):
        # Ordinary resources
        self.__tree_store.append(None, ('File',))
        self.__tree_store.append(None, ('Directory',))

        # Python files
        python_dir = self.__tree_store.append(None, ('Python',))
        self.__tree_store.append(python_dir, ('Python module',))
        self.__tree_store.append(python_dir, ('Python package',))

        # Django files
        django_dir = self.__tree_store.append(python_dir, ('Django',))
        self.__tree_store.append(django_dir, ('Django project',))
        self.__tree_store.append(django_dir, ('Django app',))

if __name__ == '__main__':
    app = Gtk.Window(Gtk.WindowType.TOPLEVEL)
    app.connect('destroy', lambda a: Gtk.main_quit())
    dlg = WizardManager(app)
    dlg.run()
    dlg.destroy()
    Gtk.main()

1 个答案:

答案 0 :(得分:0)

这里有一个提示!

#! /usr/bin/python

###########################################################
#
# Basic Gtk.TreeView Example with two sortable columns
#
###########################################################


# use  the new PyGObject binding
from gi.repository import Gtk
import os
import getpass # this is only to automatically print your home folder.

class MyWindow(Gtk.Window):

    def __init__(self):

        Gtk.Window.__init__(self, title='My Window Title')
        self.connect('delete-event', Gtk.main_quit)        

        # Gtk.ListStore will hold data for the TreeView
        # Only the first two columns will be displayed
        # The third one is for sorting file sizes as numbers
        store = Gtk.ListStore(str, str, long)
        # Get the data - see below
        self.populate_store(store)

        treeview = Gtk.TreeView(model=store)

        # The first TreeView column displays the data from
        # the first ListStore column (text=0), which contains
        # file names
        renderer_1 = Gtk.CellRendererText()        
        column_1 = Gtk.TreeViewColumn('File Name', renderer_1, text=0)
        # Calling set_sort_column_id makes the treeViewColumn sortable
        # by clicking on its header. The column is sorted by
        # the ListStore column index passed to it 
        # (in this case 0 - the first ListStore column) 
        column_1.set_sort_column_id(0)        
        treeview.append_column(column_1)

        # xalign=1 right-aligns the file sizes in the second column
        renderer_2 = Gtk.CellRendererText(xalign=1)
        # text=1 pulls the data from the second ListStore column
        # which contains filesizes in bytes formatted as strings
        # with thousand separators
        column_2 = Gtk.TreeViewColumn('Size in bytes', renderer_2, text=1)
        # Mak the Treeview column sortable by the third ListStore column
        # which contains the actual file sizes
        column_2.set_sort_column_id(1)
        treeview.append_column(column_2)

        # Use ScrolledWindow to make the TreeView scrollable
        # Otherwise the TreeView would expand to show all items
        # Only allow vertical scrollbar
        scrolled_window = Gtk.ScrolledWindow()
        scrolled_window.set_policy(
            Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        scrolled_window.add(treeview)
        scrolled_window.set_min_content_height(200)

        self.add(scrolled_window)
        self.show_all()

    def populate_store(self, store):

        directory = '/home/'+getpass.getuser()
        for filename in os.listdir(directory):
            size = os.path.getsize(os.path.join(directory, filename))
            # the second element is displayed in the second TreeView column
            # but that column is sorted by the third element
            # so the file sizes are sorted as numbers, not as strings
            store.append([filename, '{0:,}'.format(size), size])       

# The main part:
win = MyWindow()
Gtk.main()