我想实现一个允许用户通过箭头键在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()
答案 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()