我试图在PyGTK中显示一个对象树,这样当你点击一个对象时,它将移动到前一个空格,然后将它的子节点渲染到它。
例如,如果我们从选择对象1开始,则会显示其子项。
| Level 1 | Level 2 |
| ->Object 1<- | Object 1 Child 1 |
| Object 2 | Object 1 Child 2 |
| Object 3 | Object 1 Child 3 |
如果我们选择其中一个孩子,它的孩子就会显示出来。
| Level 1 | Level 2 |
| ->Object 1 Child 1<- | Object 1 Child 1 Child 1 |
| Object 1 Child 2 | Object 1 Child 1 Child 2 |
| Object 1 Child 3 | Object 1 Child 1 Child 3 |
所以我们只是遍历数据树。我实现了这个,PyGTK.TreeView
连接到PyGTK.ListStore
,其中包含对象的显示值,然后是另一个实际对象列表。
我有方法来监听PyGTK.TreeViewSelection
changed
事件以重新呈现数据
问题是,当我重建ListStore
时,对于新对象,事件会被击中两次,我无法弄清楚原因。
简单地吃第一个或第二个事件似乎不起作用,因为偶尔只会发生一个事件。
下面是一些工作示例代码,说明了我正在尝试做的事情和种类:
#!/usr/bin/python3
import gi
gi.require_version('Gtk','3.0')
gi.require_version('WebKit2','4.0')
from gi.repository import Gtk, WebKit2, Gdk
class TmpWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.set_position(Gtk.WindowPosition.CENTER)
self.connect('delete-event', Gtk.main_quit)
self.outerBox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL,spacing=6)
self.add(self.outerBox)
self.urlGrid = Gtk.Grid()
self.urlGrid.set_column_homogeneous(True)
self.urlGrid.set_row_homogeneous(True)
self.outerBox.pack_start(self.urlGrid,False,False,10)
# Set the starting lists
self.node0List = ['Object']
self.node0GridList = Gtk.ListStore(str)
self.node0GridList.append(['ObjectString'])
self.node1List = ['Object2', 'Object3']
self.node1GridList = Gtk.ListStore(str)
[self.node1GridList.append([child]) for child in self.node1List]
self.treeView0 = Gtk.TreeView.new_with_model(self.node0GridList)
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn('Node0',renderer, text=0)
self.treeView0.append_column(column)
self.scrollable_treelist0 = Gtk.ScrolledWindow()
self.scrollable_treelist0.add(self.treeView0)
self.urlGrid.attach(self.scrollable_treelist0, 0 ,0,200,10)
self.treeView1 = Gtk.TreeView.new_with_model(self.node1GridList)
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn('Node1',renderer, text=0)
self.treeView1.append_column(column)
self.scrollable_treelist1 = Gtk.ScrolledWindow()
self.scrollable_treelist1.add(self.treeView1)
self.urlGrid.attach_next_to(self.scrollable_treelist1,self.scrollable_treelist0,Gtk.PositionType.RIGHT, 200,10)
self.treeView0SignalId = self.treeView0.get_selection().connect('changed',self.node0Selection)
self.treeView1SignalId = self.treeView1.get_selection().connect('changed',self.node1Selection)
self.show_all()
def node0Selection(self, selection):
print('Hitting Node0 Selection Handler')
self.treeView0.get_selection().handler_block(self.treeView0SignalId)
self.treeView1.get_selection().handler_block(self.treeView1SignalId)
tmp = self.node0List
self.node0List = self.node1List
self.node1List = tmp
self.node0GridList.clear()
[self.node0GridList.append([child]) for child in self.node0List]
self.node1GridList.clear()
[self.node1GridList.append([child]) for child in self.node1List]
self.treeView0.get_selection().handler_unblock(self.treeView0SignalId)
self.treeView1.get_selection().handler_unblock(self.treeView1SignalId)
def node1Selection(self, selection):
print('Hitting Node1 Selection Handler')
self.treeView0.get_selection().handler_block(self.treeView0SignalId)
self.treeView1.get_selection().handler_block(self.treeView1SignalId)
tmp = self.node0List
self.node0List = self.node1List
self.node1List = tmp
self.node0GridList.clear()
[self.node0GridList.append([child]) for child in self.node0List]
self.node1GridList.clear()
[self.node1GridList.append([child]) for child in self.node1List]
self.treeView0.get_selection().handler_unblock(self.treeView0SignalId)
self.treeView1.get_selection().handler_unblock(self.treeView1SignalId)
if __name__ == '__main__':
TmpWindow()
Gtk.main()
单击列表中的任何项目时,应在处理程序被命中时在控制台中显示一条消息。请注意,只需单击鼠标,它们就会连续两次被击中。
答案 0 :(得分:0)
我最终通过在tree_view row-activated
事件上放置我的点击处理程序来解决这个问题。而不是选择改变事件。
self.tree_views[0].connect('row-activated',self.node_one_selection)
我仍然接受一个答案,为什么我必须这样做(好奇我在思考GTK小部件时的缺陷是什么)。