PySide Qt 在叶项处插入行并更新视图
Posted
技术标签:
【中文标题】PySide Qt 在叶项处插入行并更新视图【英文标题】:PySide Qt insert row at leaf item and update view 【发布时间】:2015-03-26 06:18:05 【问题描述】:我有这个大部分工作的代码,使用户能够将项目添加到树结构中。只要您不向叶项(没有子项的项)添加项,这就可以正常工作。
如果项目没有子项目,那么在第一次添加子项目时,视图根本不会更新。您可以通过卷起父项并重新展开它来更新视图。或者,添加第二个子项会导致视图更新(您可以看到两个项都添加了)。
如何在将第一个子项添加到叶项后更新视图?
更新:您也可以双击新的父级,它的子级将显示,但没有扩展小部件。似乎没有发生的是,在满足上述条件之一之前,小扩展项小部件不会显示。
from PySide import QtCore, QtGui
import sys
model_data = [
[1, [2, [3, 4]]],
[5, [6, 7]],
[8, [9]],
[10]
]
class MyData:
def __init__(self, number, parent=None):
''''''
self.number = number
self.children = []
self.parent = parent
if parent is not None:
parent.addChild(self)
def row(self):
''''''
row = None
if self.parent is None:
row = 0
else:
for i, item in enumerate(self.parent.children):
if item == self:
row = i
break
return row
def addChild(self, item):
''''''
self.children.append(item)
item.parent = self
class TreeModel(QtCore.QAbstractItemModel):
def __init__(self, top, *args, **kwargs):
''''''
super(TreeModel, self).__init__(*args, **kwargs)
self.__top = top
def index(self, row, column, parent=QtCore.QModelIndex()):
''''''
if parent.isValid():
parent_node = parent.internalPointer()
node = parent_node.children[row]
index = self.createIndex(row, column, node)
else:
index = self.createIndex(row, column, self.__top)
return index
def parent(self, index):
''''''
if index.isValid():
node = index.internalPointer()
parent = node.parent
if parent is None:
parent_index = QtCore.QModelIndex()
else:
parent_index = self.createIndex(parent.row(), 0, parent)
else:
parent_index = QtCore.QModelIndex()
return parent_index
def rowCount(self, index=QtCore.QModelIndex()):
''''''
node = index.internalPointer()
if node is None:
count = 1
else:
count = len(node.children)
return count
def columnCount(self, index=QtCore.QModelIndex()):
''''''
return 1
def data(self, index, role=QtCore.Qt.DisplayRole):
''''''
if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
node = index.internalPointer()
data = str(node.number)
else:
data = None
return data
def addChild(self, index, child):
self.beginInsertRows(index, self.rowCount(index), self.rowCount(index)+1)
parent = index.internalPointer()
parent.addChild(child)
self.endInsertRows()
class Window(QtGui.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.build_model()
self.add_item_action = QtGui.QAction('New &Item', self)
self.add_item_action.triggered.connect(self.add_item)
self.view = QtGui.QTreeView()
self.view.setModel(self.model)
self.setCentralWidget(self.view)
self.show()
def build_model(self):
def recurse(parent, children_data):
for child_data in children_data:
if isinstance(child_data, list):
recurse(child, child_data)
else:
child = MyData(child_data, parent=parent)
top = MyData(0)
for i, next in enumerate(model_data):
recurse(top, next)
self.model = TreeModel(top)
def add_item(self):
''''''
index = self.view.currentIndex()
new_item = MyData(0)
self.model.addChild(index, new_item)
def contextMenuEvent(self, event):
''''''
contextMenu = QtGui.QMenu()
contextMenu.addAction(self.add_item_action)
contextMenu.exec_(event.globalPos())
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window()
sys.exit(app.exec_())
【问题讨论】:
也许你可以使用void QAbstractItemView::update (const QModelIndex &index)
(是的,它的c++,但是python绑定应该有类似的方法
【参考方案1】:
除非模型知道布局发生了更改,否则它不会始终正确更新。所以试试这个:
def addChild(self, index, child):
...
self.endInsertRows()
self.layoutChanged.emit()
【讨论】:
谢谢,解决我的问题,我已经调用了 beginInsertRows 和 endInsertRows,没有帮助,添加 self.layoutChanged.emit() 后,它可以工作了。以上是关于PySide Qt 在叶项处插入行并更新视图的主要内容,如果未能解决你的问题,请参考以下文章