我實現了一個自定義的TreeModel在PyGI(GTK3)以下方式(如建議here 和here):GTK3中的TreeModel(PyGI)第一次調用do_iter_next(iter)?
test.py
from gi.repository import Gtk
class Store(GObject.Object, Gtk.TreeModel):
def __init__(self):
self.data = [[i*j for i in range(10)] for j in range(10)] #multiplication table
super(Store, self).__init__()
#boilerplate TreeModel interface implementation
def do_get_flags(self):
print "do_get_flags called"
return Gtk.TreeModelFlags.LIST_ONLY
def do_get_n_columns(self):
print "do_get_n_columns called"
return len(self.data[0])
def do_get_column_type(self, index):
print "do_get_column_type called; index = %s"%(index)
if index < 10:
return str
else:
raise IndexError
def do_get_iter(self, path):
print "do_get_iter called; path = %s"%(path)
indices = path.get_indices()
if indices[0] < len(self.alignment.sequences):
iterator = Gtk.TreeIter()
iterator.user_data = indices[0]
print "iterator.user_data = %s, iterator = %s" % (iterator.user_data, iterator)
return (True, iterator)
else:
return (False, None)
def do_get_path(self, iterator):
print "do_get_path called; iter = %s" % (iter)
if iterator.user_data is not None:
path = Gtk.TreePath(iterator.user_data)
return path
else:
return None
def do_get_value(self, iterator, column_index):
print "do_get_value called; iterator = %s, column_index = %s"%(iterator, column_index)
item = self.data[iterator.user_data][column_index]
def do_iter_next(self, iterator):
print "do_iter_next_called; iterator = %s"%(iterator)
#returns next iterator
if not hasattr(iterator, "user_data"):
print self.do_get_path(iterator)
return
else:
print "user data = %s" % (iterator.user_data)
try:
return self.do_get_iter(Gtk.TreePath((iterator.user_data+1,)))
except IndexError:
return None
def do_iter_has_child(self, iterator):
print "do_iter_has_child called; rowref = %s" % (iterator)
return False
def do_iter_nth_child(self, iterator, index):
print "do_iter_nth_child called; iterator = %s, index = %s" % (iterator, index)
output_iterator = Gtk.TreeIter()
output_iterator.user_data = index
return (True, output_iterator)
def do_iter_parent(self, child):
print "do_iter_parent called; child = %s" % (child)
return None
def main():
model = Store()
view = Gtk.TreeView(model)
for index, column in enumerate(alignment):
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(str(index))
column.pack_start(renderer, False)
column.add_attribute(renderer, "markup", index)
#column.props.sizing = Gtk.TreeViewColumnSizing.FIXED
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()
return window
if __name__ == "__main__":
window = main()
window.connect('destroy', Gtk.main_quit)
Gtk.main()
可惜,這實現不工作,由於瘋狂的行爲do_iter_next()
。看看日誌文件的內容,創建由python test.py &> test.log
:
test.log中
do_get_n_columns called
do_get_column_type called; index = 0
do_get_flags called
do_get_iter called; path = 0
iterator.user_data = 0, iterator = <GtkTreeIter at 0x8797cb0>
do_iter_next_called; iterator = <GtkTreeIter at 0xbfb243c0>
user data = None
Traceback (most recent call last):
File "minimal_example.py", line 65, in do_iter_next
return self.do_get_iter(Gtk.TreePath((iterator.user_data+1,)))
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
do_iter_next_called; iterator = <GtkTreeIter at 0xbfb243c0>
user data = None
Traceback (most recent call last):
File "minimal_example.py", line 65, in do_iter_next
return self.do_get_iter(Gtk.TreePath((iterator.user_data+1,)))
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
do_iter_next_called; iterator = <GtkTreeIter at 0xbfb243c0>
user data = None
你想過爲什麼第一do_get_iter()返回一個迭代器,然後do_iter_next(任何想法)發生在輸入另一個一個是空的user_data。另外,你是否明白,是否user_data
是由GTK3作者分配的特定領域?參考手冊沒有提到它,但爲什麼然後它出現在0xbfb243c0我的神祕iter?