gpt4 book ai didi

qt - 如何创建将QAbstractItemModel的节点展平到PySide中的列表的代理模型?

转载 作者:行者123 更新时间:2023-12-04 11:24:55 24 4
gpt4 key购买 nike

我有一个由自定义QAbstractItemModel表示的节点层次结构。是否可以创建一个将层次结构展平为列表的代理模型,以允许我在QListView中显示所有节点/项目(没有代理,仅显示树的第一级)?

A                           A
+---1 1
2 2
+--3 3
4 => 4
B B
+---5 5
6 6
+--7 7
8 8

谢谢,
菲普斯

最佳答案

强制QTreeView看起来像 ListView ,这样更容易:

view = QtGui.QTreeView()
view.setModel(model)
view.expandAll()
view.setIndentation(0)
view.header().hide()

如果您真的希望这样做,那么代理并不是最琐碎的事情,因为它需要保留源模型的结构模型。对于更改其结构的源模型,代理还必须跟踪源模型的结构。

首先,下面是具有静态结构的模型的最小实现。我仅在Python 3.3上进行了测试。更改将在 View 之间传播-您可以在任一 View 中编辑项目的文本,然后将修改基础树模型,并适当通知另一个 View 。

代理应该只是传递列表模型,因为它们已经很平坦了。为了说明这种透明性,右 Pane 是在中间 Pane 中查看的与代理相连的代理的 ListView 。在中间 Pane 中查看的代理被附加到在左 Pane 中查看的树模型。

很高兴接受那些真正了解Python/PySide的人的编辑。目前,我对Python的了解非常有趣。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from PySide import QtCore, QtGui

class FlatProxyModel(QtGui.QAbstractProxyModel):
@QtCore.Slot(QtCore.QModelIndex, QtCore.QModelIndex)
def sourceDataChanged(self, topLeft, bottomRight):
self.dataChanged.emit(self.mapFromSource(topLeft), \
self.mapFromSource(bottomRight))
def buildMap(self, model, parent = QtCore.QModelIndex(), row = 0):
if row == 0:
self.m_rowMap = {}
self.m_indexMap = {}
rows = model.rowCount(parent)
for r in range(rows):
index = model.index(r, 0, parent)
print('row', row, 'item', model.data(index))
self.m_rowMap[index] = row
self.m_indexMap[row] = index
row = row + 1
if model.hasChildren(index):
row = self.buildMap(model, index, row)
return row
def setSourceModel(self, model):
QtGui.QAbstractProxyModel.setSourceModel(self, model)
self.buildMap(model)
print(flush = True)
model.dataChanged.connect(self.sourceDataChanged)
def mapFromSource(self, index):
if index not in self.m_rowMap: return QtCore.QModelIndex()
#print('mapping to row', self.m_rowMap[index], flush = True)
return self.createIndex(self.m_rowMap[index], index.column())
def mapToSource(self, index):
if not index.isValid() or index.row() not in self.m_indexMap:
return QtCore.QModelIndex()
#print('mapping from row', index.row(), flush = True)
return self.m_indexMap[index.row()]
def columnCount(self, parent):
return QtGui.QAbstractProxyModel.sourceModel(self)\
.columnCount(self.mapToSource(parent))
def rowCount(self, parent):
#print('rows:', len(self.m_rowMap), flush=True)
return len(self.m_rowMap) if not parent.isValid() else 0
def index(self, row, column, parent):
#print('index for:', row, column, flush=True)
if parent.isValid(): return QtCore.QModelIndex()
return self.createIndex(row, column)
def parent(self, index):
return QtCore.QModelIndex()
def __init__(self, parent = None):
super(FlatProxyModel, self).__init__(parent)

if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)

model = QtGui.QStandardItemModel()
names = ['Foo', 'Bar', 'Baz']
for first in names:
row = QtGui.QStandardItem(first)
for second in names:
row.appendRow(QtGui.QStandardItem(first+second))
model.appendRow(row)

proxy = FlatProxyModel()
proxy.setSourceModel(model)

nestedProxy = FlatProxyModel()
nestedProxy.setSourceModel(proxy)

w = QtGui.QWidget()
layout = QtGui.QHBoxLayout(w)
view = QtGui.QTreeView()
view.setModel(model)
view.expandAll()
view.header().hide()
layout.addWidget(view)
view = QtGui.QListView()
view.setModel(proxy)
layout.addWidget(view)
view = QtGui.QListView()
view.setModel(nestedProxy)
layout.addWidget(view)
w.show()

sys.exit(app.exec_())

关于qt - 如何创建将QAbstractItemModel的节点展平到PySide中的列表的代理模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21564976/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com