简体   繁体   English

TreeView选择处理程序触发两次

[英]TreeView Selection Handler triggering twice

I am trying to display a Tree of objects in PyGTK such that when you click on one object, it will move to the previous space and then render its children where it was. 我试图在PyGTK中显示一棵对象树,以便当您单击一个对象时,它将移动到上一个空间,然后将其子对象呈现在原处。

For example, if we start with object 1 selected, its children will be displayed. 例如,如果我们从选定的对象1开始,将显示其子对象。

| Level 1      | Level 2          |
| ->Object 1<- | Object 1 Child 1 |  
| Object 2     | Object 1 Child 2 |  
| Object 3     | Object 1 Child 3 |   

If we then select one of its children, its children will get displayed. 如果我们随后选择其子级之一,则将显示其子级。

| 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 |

So we are just traversing through the tree of data. 因此,我们只是遍历数据树。 I have implemented this with PyGTK.TreeView 's connected to PyGTK.ListStore 's that hold the display value of the object, and then another list of the actual objects themselves. 我曾与实现了这个PyGTK.TreeView的连接PyGTK.ListStore的持有对象的显示值,然后实际的对象本身的另一个列表。
I have methods to listen for the PyGTK.TreeViewSelection changed event to do the re-rendering of the data. 我有方法可以侦听PyGTK.TreeViewSelection changed事件,以重新呈现数据。
The problem is, when I am rebuilding the ListStore 's, for the new object, the event is getting hit twice, and I can't figure out why. 问题是,当我重建ListStore ,对于新对象,该事件被击中两次,而我不知道为什么。
Simply eating the first or second event doesn't seem to work because occasionally only one event is fired. 仅仅吃掉第一个或第二个事件似乎不起作用,因为偶尔会触发一个事件。

Below is some working sample code illustrating what is happening and kind of what I am trying to do: 以下是一些工作示例代码,它们说明了正在发生的事情以及我正在尝试做的事情:

#!/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()

Clicking on any of the items in the list should display a message in the console when the handler is hit. 单击列表中的任何项目时,单击处理程序时,控制台中都会显示一条消息。 Notice that they are getting hit twice in a row with a single mouse click. 请注意,单击鼠标连续将它们击中两次。

I ended up working around this by putting my on-click handlers on the tree_view row-activated events. 我最终通过将单击处理程序放在tree_view row-activated事件上来解决此问题。 instead of selection changed events. 而不是选择更改的事件。

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

I'll still accept an answer for why I have to do that (curious what my flaw in thinking about GTK widgets is/was). 我仍然会接受一个答案,说明为什么我必须这样做(很好奇我在思考GTK小部件时的缺点是/过去)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM