(PYQT)QTREEVIEW-想要扩展/倒塌所有儿童和孙子
题
我希望能够在Qtreeview中扩展或崩溃。我正在使用pyqt4。
我知道Qtreeview的所有孩子都有限制为 *的所有儿童功能,但是我需要两件事:它需要绑定到其他关键组合(换档空间),而且我也需要能够崩溃所有的孩子。
这是我到目前为止尝试的:我有一个QTREEVIEW的子类,其中我正在检查Shift Space键组合。我知道Qmodelindex会让我挑选一个具有“孩子”功能的特定孩子,但这需要了解孩子的数量。一世 是 能够通过查看InternalPointer来获取孩子的计数,但这只会为我提供层次结构的第一级信息。如果我尝试使用递归,我可以得到一大堆孩子的计数,但是后来我如何将这些转换回有效的QmodelIndex感到迷失。
这是一些代码:
def keyPressEvent(self, event):
"""
Capture key press events to handle:
- enable/disable
"""
#shift - space means toggle expanded/collapsed for all children
if (event.key() == QtCore.Qt.Key_Space and
event.modifiers() & QtCore.Qt.ShiftModifier):
expanded = self.isExpanded(self.selectedIndexes()[0])
for cellIndex in self.selectedIndexes():
if cellIndex.column() == 0: #only need to call it once per row
#I can get the actual object represented here
item = cellIndex.internalPointer()
#and I can get the number of children from that
numChildren = item.get_child_count()
#but now what? How do I convert this number into valid
#QModelIndex objects? I know I could use:
# cellIndex.child(row, 0)
#to get the immediate children's QModelIndex's, but how
#would I deal with grandchildren, great grandchildren, etc...
self.setExpanded(cellIndex, not(expanded))
return
这是我正在调查的递归方法的开始,但是当实际试图设置扩展状态时,我会卡住,因为一旦进入递归,我就会与任何有效的Qmodelindex失去“联系” ...
def toggle_expanded(self, item, expand):
"""
Toggles the children of item (recursively)
"""
for row in range(0,item.get_child_count()):
newItem = item.get_child_at_row(row)
self.toggle_expanded(newItem, expand)
#well... I'm stuck here because I'd like to toggle the expanded
#setting of the "current" item, but I don't know how to convert
#my pointer to the object represented in the tree view back into
#a valid QModelIndex
#self.setExpanded(?????, expand) #<- What I'd like to run
print "Setting", item.get_name(), "to", str(expand) #<- simple debug statement that indicates that the concept is valid
感谢所有人抽出宝贵的时间来看看这个!
解决方案
好的...兄弟姐妹实际上并没有把我带到我想去的地方。我设法使代码工作如下(这似乎是一个不错的实现)。仍然对ebral教授表示敬意,他以兄弟姐妹的想法使我走上正确的轨道(事实证明,我需要使用qmodelindex.child(行,列),然后从那里递归迭代)。
请注意,代码中存在以下假设:它假设您的基础数据存储对象能够报告他们拥有多少个孩子(我的代码中的get_child_count())。如果不是这种情况,您将以某种方式必须以不同的方式获得一个不同的计数……也许只要任意尝试获取孩子索引 - 使用qmodelindex.Child(row,col),而行不断增加,直到您回来直到您回来无效索引? - 这就是欧布拉尔教授的建议,我仍然可能会尝试(这只是我已经有一种简单的方法来通过从数据存储中要求来获取孩子计数)。
另请注意,我实际上是根据我正在扩展还是崩溃的,实际上在递归中的不同点上扩展了/碰撞。这是因为,通过反复试验,我发现,如果我只是在代码中的一个地方进行了动画树视图就会结结巴巴和弹出。现在,通过根据我是否处于最高级别(即我影响的分支的根部 - 不是整个TreeView的根)来逆转我的执行顺序,我会得到一个很好的平滑动画。这是在下面记录的。
以下代码在QTREEVIEW子类中。
#---------------------------------------------------------------------------
def keyPressEvent(self, event):
if (event.key() == QtCore.Qt.Key_Space and self.currentIndex().column() == 0):
shift = event.modifiers() & QtCore.Qt.ShiftModifier
if shift:
self.expand_all(self.currentIndex())
else:
expand = not(self.isExpanded(self.currentIndex()))
self.setExpanded(self.currentIndex(), expand)
#---------------------------------------------------------------------------
def expand_all(self, index):
"""
Expands/collapses all the children and grandchildren etc. of index.
"""
expand = not(self.isExpanded(index))
if not expand: #if collapsing, do that first (wonky animation otherwise)
self.setExpanded(index, expand)
childCount = index.internalPointer().get_child_count()
self.recursive_expand(index, childCount, expand)
if expand: #if expanding, do that last (wonky animation otherwise)
self.setExpanded(index, expand)
#---------------------------------------------------------------------------
def recursive_expand(self, index, childCount, expand):
"""
Recursively expands/collpases all the children of index.
"""
for childNo in range(0, childCount):
childIndex = index.child(childNo, 0)
if expand: #if expanding, do that first (wonky animation otherwise)
self.setExpanded(childIndex, expand)
subChildCount = childIndex.internalPointer().get_child_count()
if subChildCount > 0:
self.recursive_expand(childIndex, subChildCount, expand)
if not expand: #if collapsing, do it last (wonky animation otherwise)
self.setExpanded(childIndex, expand)
其他提示
Model.RowCount(索引)是您想要的方法。
model = index.model() # or some other way of getting it
for i in xrange(model.rowCount(index)):
child = model.index(i,0, index)
# do something with child
model.index(行,col,parent)基本上与调用index.child(row,col);只是间接较少。
我建议使用继承QTREEVIEW的QTREEWIDGET。然后,您可以抓住孩子作为QtreewidgetItem。
由于您不想使用QTREEWIDGET,但要坚持当前的型号。.您可以通过使用.isvalid()的“可能的”孩子迭代。不过,您不应使用internalPointer()。取而代之的是使用您拥有的牢房,因为它是原始的模饰。然后尝试找到它的兄弟姐妹。就像是
x = 0; y =0
while cellIndex.sibling(x, y).isValid():
child = cellIndex.sibling(x, y)
x += 1