1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
# -*- Mode: Python; py-indent-offset: 4 -*-
# pygobject - Python bindings for the GObject library
# Copyright (C) 2014 Simon Feltman
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, see <http://www.gnu.org/licenses/>.
title = "Tree Model with Large Data"
description = """
Implementation of the Gtk.TreeModel interface to create a custom model.
The demo uses a fake data store (it is not backed by a Python list) and is for
the purpose of showing how to override the TreeModel interfaces virtual methods.
"""
from gi.repository import GObject
from gi.repository import GLib
from gi.repository import Gtk
class Model(GObject.Object, Gtk.TreeModel):
columns_types = (str, str)
item_count = 100000
item_data = 'abcdefghijklmnopqrstuvwxyz'
def __init__(self):
super(Model, self).__init__()
def do_get_flags(self):
return Gtk.TreeModelFlags.LIST_ONLY
def do_get_n_columns(self):
return len(self.columns_types)
def do_get_column_type(self, n):
return self.columns_types[n]
def do_get_iter(self, path):
# Return False and an empty iter when out of range
index = path.get_indices()[0]
if index < 0 or index >= self.item_count:
return False, None
it = Gtk.TreeIter()
it.user_data = index
return True, it
def do_get_path(self, it):
return Gtk.TreePath([it.user_data])
def do_get_value(self, it, column):
if column == 0:
return str(it.user_data)
elif column == 1:
return self.item_data
def do_iter_next(self, it):
# Return False if there is not a next item
next = it.user_data + 1
if next >= self.item_count:
return False
# Set the iters data and return True
it.user_data = next
return True
def do_iter_previous(self, it):
prev = it.user_data - 1
if prev < 0:
return False
it.user_data = prev
return True
def do_iter_children(self, parent):
# If parent is None return the first item
if parent is None:
it = Gtk.TreeIter()
it.user_data = 0
return True, it
return False, None
def do_iter_has_child(self, it):
return it is None
def do_iter_n_children(self, it):
# If iter is None, return the number of top level nodes
if it is None:
return self.item_count
return 0
def do_iter_nth_child(self, parent, n):
if parent is not None or n >= self.item_count:
return False, None
elif parent is None:
# If parent is None, return the nth iter
it = Gtk.TreeIter()
it.user_data = n
return True, it
def do_iter_parent(self, child):
return False, None
def main(demoapp=None):
model = Model()
# Use fixed-height-mode to get better model load and display performance.
view = Gtk.TreeView(fixed_height_mode=True, headers_visible=False)
column = Gtk.TreeViewColumn()
column.props.sizing = Gtk.TreeViewColumnSizing.FIXED
renderer1 = Gtk.CellRendererText()
renderer2 = Gtk.CellRendererText()
column.pack_start(renderer1, expand=True)
column.pack_start(renderer2, expand=True)
column.add_attribute(renderer1, 'text', 0)
column.add_attribute(renderer2, 'text', 1)
view.append_column(column)
scrolled = Gtk.ScrolledWindow()
scrolled.add(view)
window = Gtk.Window(title=title)
window.set_size_request(480, 640)
window.add(scrolled)
window.show_all()
GLib.timeout_add(10, lambda *args: view.set_model(model))
return window
if __name__ == "__main__":
window = main()
window.connect('destroy', Gtk.main_quit)
Gtk.main()
|