TreeView选择处理程序触发两次

时间:2018-01-17 04:49:43

标签: python python-3.x pygtk

我试图在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()

单击列表中的任何项目时,应在处理程序被命中时在控制台中显示一条消息。请注意,只需单击鼠标,它们就会连续两次被击中。

1 个答案:

答案 0 :(得分:0)

我最终通过在tree_view row-activated事件上放置我的点击处理程序来解决这个问题。而不是选择改变事件。

self.tree_views[0].connect('row-activated',self.node_one_selection)

我仍然接受一个答案,为什么我必须这样做(好奇我在思考GTK小部件时的缺陷是什么)。