我如何在保持当前折叠/展开状态不变的情况下,为整个模型正确更新第二列的显示文本?我想在用户在前缀输入字段中键入内容时进行更新。
“新名称”显示文本是模型中每个项目的UserRole中存在的类Object的属性。理想情况下,当类对象的属性“新名称”更改时,UI会自动更新以显示正确的值。
这是通过在模型中使用额外的自定义角色来完成的吗?还是子类化QstandardItem或QstandardItemModel的某种方式?我不确定推荐的解决方案是什么?
我正在使用PySide和Python 2.7
################################################################################
# Imports
################################################################################
import os, sys, random
sys.path.append(os.environ.get('PS_SITEPACKAGES'))
from Qt import QtCore, QtWidgets, QtGui
################################################################################
# Objects
################################################################################
class AbstractObject(object):
def __init__(self, name):
self._name = name
self._children = []
self._newName = ''
# methods
def children(self):
return self._children
def getName(self):
return self._name
def getNewName(self):
return self._newName
def setNewName(self, value):
self._newName = value
class PersonObject(AbstractObject):
def __init__(self, obj):
AbstractObject.__init__(self, obj)
class CityObject(AbstractObject):
def __init__(self, obj):
AbstractObject.__init__(self, obj)
class StateObject(AbstractObject):
def __init__(self, name):
AbstractObject.__init__(self, name)
################################################################################
# Widgets
################################################################################
class OutlinerTreeView(QtWidgets.QTreeView):
def __init__(self):
QtWidgets.QTreeView.__init__(self)
self.model = QtGui.QStandardItemModel()
self.model.setHorizontalHeaderLabels(['Name', 'New Name'])
# self.setHeaderHidden(True)
self.setUniformRowHeights(True)
self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.setModel(self.model)
# begin
self.populateModel()
# methods
def getDummyData(self):
'''
Description:
Returns scene hierarchy layout of Layers, Objects, Materials.
'''
states = ['Alabama', 'Alaska', 'American Samoa', 'Arizona', 'Arkansas']
cities = ['New York', 'Los Angeles', 'Chicago', 'Houston', 'Phoenix', 'Philadelphia', 'San Antonio', 'San Diego', 'Dallas', 'San Jose', 'Detroit', 'Jacksonville', 'Indianapolis', 'San Francisco']
layout = []
for i in states:
state = StateObject(i)
# for each state create random city with people
for x in range(random.randint(0,4)):
cityName = cities[random.randint(0, len(cities)-1)]
city = CityObject(cityName)
state._children.append(city)
# append main layout
layout.append(state)
return layout
def appendItem(self, obj, parent):
col1 = QtGui.QStandardItem()
col1.setData(obj.getName(), role=QtCore.Qt.DisplayRole)
col1.setData(obj, role=QtCore.Qt.UserRole)
parent.appendRow([col1])
# Recursive
for x in obj.children():
self.appendItem(x, col1)
def populateModel(self):
items = self.getDummyData()
for x in items:
self.appendItem(x, self.model.invisibleRootItem())
class Dialog(QtWidgets.QDialog):
def __init__(self):
super(Dialog, self).__init__()
self.treeView = OutlinerTreeView()
self.prefix = QtWidgets.QLineEdit()
self.prefix.setPlaceholderText('Prefix')
self.mainLayout = QtWidgets.QVBoxLayout()
self.mainLayout.addWidget(self.treeView)
self.mainLayout.addWidget(self.prefix)
self.setLayout(self.mainLayout)
################################################################################
# Unit Test
################################################################################
def unitTest_outlinerTreeView():
mxs.clearlistener()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
dlg = Dialog()
dlg.show()
sys.exit(app.exec_())