Dictionary Python的Qt:Qtreeview(来自字典)
以下使用Qt的“简单树模型示例”作为基础,从给定的字典构建大部分QTreeViewDictionary Python的Qt:Qtreeview(来自字典),dictionary,parent,children,qabstractitemmodel,Dictionary,Parent,Children,Qabstractitemmodel,以下使用Qt的“简单树模型示例”作为基础,从给定的字典构建大部分QTreeView #!/usr/bin/env python # -*- coding: utf-8 -*- import sys from PySide2.QtWidgets import QApplication, QWidget, QGroupBox, QHBoxLayout, QVBoxLayout, QTreeView from PySide2.QtCore import Qt, QAbstractItemModel,
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from PySide2.QtWidgets import QApplication, QWidget, QGroupBox, QHBoxLayout, QVBoxLayout, QTreeView
from PySide2.QtCore import Qt, QAbstractItemModel, QModelIndex
class GUIWindow(QWidget):
def __init__(self, parent=None):
super(GUIWindow, self).__init__(parent)
""" Setup UI """
self.setWindowTitle("QTreeView from Dictionary")
groupbox_model = QGroupBox('TreeView') # Create a Group Box for the Model
hbox_model = QHBoxLayout() # Create a Horizontal layout for the Model
vbox = QVBoxLayout() # Create a Vertical layout for the Model Horizontal layout
tree_view = QTreeView() # Instantiate the View
headers = ["Dictionary"]
tree = {'Root': {"Level_1": {"Item_1": 1.10, "Item_2": 1.20, "Item_3": 1.30},
"Level_2": {"SubLevel_1":
{"SubLevel_1_item1": 2.11, "SubLevel_1_Item2": 2.12, "SubLevel_1_Item3": 2.13},
"SubLevel_2":
{"SubLevel_2_Item1": 2.21, "SubLevel_2_Item2": 2.22, "SubLevel_2_Item3": 2.23}},
"Level_3": {"Item_1": 3.10, "Item_2": 3.20, "Item_3": 3.30}}}
# Set the models
model = TreeModel(headers, tree)
tree_view.setModel(model)
hbox_model.addWidget(tree_view) # Add the Widget to the Model Horizontal layout
groupbox_model.setLayout(hbox_model) # Add the hbox_model to layout of group box
vbox.addWidget(groupbox_model) # Add groupbox elements to vbox
self.setLayout(vbox)
class TreeModel(QAbstractItemModel):
def __init__(self, header, data, parent=None):
super(TreeModel, self).__init__(parent)
""" subclassing the standard interface item models must use and
implementing index(), parent(), rowCount(), columnCount(), and data()."""
rootData = header
self.rootItem = TreeNode(rootData)
level = 0
self.createData(data, level)
def createData(self, data, level):
parents = [self.rootItem]
sublevel = 2
if type(data) == dict:
level += 1
for key, values in data.items():
if level > sublevel:
parents.append(parents[-1].child(parents[-1].childCount() - 1))
if level > sublevel + 1:
sublevel += 1
if level > sublevel:
parents.append(parents[-1].child(parents[-1].childCount() - 1))
# Append a new item to the current parent's list of children
parent_item = parents[-1]
parent_item.insertChildren(parent_item.childCount())
parent_item.child(parent_item.childCount() - 1).setData([key])
self.createData(values, level) # Recursion to iterate through nested dict
sublevel += 1
def index(self, row, column, index=QModelIndex()):
""" Returns the index of the item in the model specified by the given row, column and parent index """
if not self.hasIndex(row, column, index):
return QModelIndex()
if not index.isValid():
item = self.rootItem
else:
item = index.internalPointer()
child = item.child(row)
if child:
return self.createIndex(row, column, child)
return QModelIndex()
def parent(self, index):
""" Returns the parent of the model item with the given index
If the item has no parent, an invalid QModelIndex is returned """
if not index.isValid():
return QModelIndex()
item = index.internalPointer()
if not item:
return QModelIndex()
parent = item.parentItem
if parent == self.rootItem:
return QModelIndex()
else:
return self.createIndex(parent.childNumber(), 0, parent)
def rowCount(self, index=QModelIndex()):
""" Returns the number of rows under the given parent
When the parent is valid it means that rowCount is returning the number of children of parent """
parent = self.getItem(index)
return parent.childCount()
def columnCount(self, index=QModelIndex()):
""" Returns the number of columns for the children of the given parent """
if index.isValid():
return index.internalPointer().columnCount()
else:
return self.rootItem.columnCount()
def data(self, index, role=Qt.DisplayRole):
""" Returns the data stored under the given role for the item referred to by the index """
if index.isValid() and role == Qt.DisplayRole:
return index.internalPointer().data(index.column())
elif not index.isValid():
return self.rootItem.getData()
def getItem(self, index):
""" Retrieves the tree node with a given index """
if index.isValid():
item = index.internalPointer()
if item:
return item
return self.rootItem
def headerData(self, section, orientation, role):
""" Returns the data for the given role and section in the header with the specified orientation """
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.rootItem.data(section)
class TreeNode(object):
def __init__(self, data, parent=None):
self.parentItem = parent
self.itemData = data
self.children = []
def child(self, row):
return self.children[row]
def childCount(self):
return len(self.children)
def childNumber(self):
if self.parentItem:
return self.parentItem.children.index(self)
return 0
def columnCount(self):
return 1
def data(self, column):
return self.itemData[column]
def insertChildren(self, position):
item = TreeNode([1], self)
self.children.insert(position, item)
return True
def parent(self):
return self.parentItem
def setData(self, value):
self.itemData[0] = value
return True
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle("plastique") # ("cleanlooks")
form = GUIWindow()
form.show()
sys.exit(app.exec_())
以上是一个好方法吗
以及需要哪些代码(必需/更改)来:
感谢您的建议。已解决-如果有兴趣,下面显示了解决这两个问题的完整代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from PySide2.QtWidgets import QApplication, QWidget, QGroupBox, QHBoxLayout, QVBoxLayout, QTreeView
from PySide2.QtCore import Qt, QAbstractItemModel, QModelIndex
class GUIWindow(QWidget):
def __init__(self, parent=None):
super(GUIWindow, self).__init__(parent)
""" Setup UI """
self.setWindowTitle("QTreeView from Dictionary")
groupbox_model = QGroupBox('TreeView') # Create a Group Box for the Model
hbox_model = QHBoxLayout() # Create a Horizontal layout for the Model
vbox = QVBoxLayout() # Create a Vertical layout for the Model Horizontal layout
tree_view = QTreeView() # Instantiate the View
headers = ["Dictionary Keys", "Dictionary Values"]
tree = {'Root': {"Level_1": {"Item_1": 1.10, "Item_2": 1.20, "Item_3": 1.30},
"Level_2": {"SubLevel_1":
{"SubLevel_1_item1": 2.11, "SubLevel_1_Item2": 2.12, "SubLevel_1_Item3": 2.13},
"SubLevel_2":
{"SubLevel_2_Item1": 2.21, "SubLevel_2_Item2": 2.22,
"SubLevel_2_Item3": 2.23}},
"Level_3": {"Item_1": 3.10, "Item_2": 3.20, "Item_3": 3.30}}}
# Set the models
model = TreeModel(headers, tree)
tree_view.setModel(model)
tree_view.expandAll()
tree_view.resizeColumnToContents(0)
hbox_model.addWidget(tree_view) # Add the Widget to the Model Horizontal layout
groupbox_model.setLayout(hbox_model) # Add the hbox_model to layout of group box
vbox.addWidget(groupbox_model) # Add groupbox elements to vbox
self.setLayout(vbox)
class TreeModel(QAbstractItemModel):
def __init__(self, headers, data, parent=None):
super(TreeModel, self).__init__(parent)
""" subclassing the standard interface item models must use and
implementing index(), parent(), rowCount(), columnCount(), and data()."""
rootData = [header for header in headers]
self.rootItem = TreeNode(rootData)
indent = -1
self.parents = [self.rootItem]
self.indentations = [0]
self.createData(data, indent)
def createData(self, data, indent):
if type(data) == dict:
indent += 1
position = 4 * indent
for dict_keys, dict_values in data.items():
if position > self.indentations[-1]:
if self.parents[-1].childCount() > 0:
self.parents.append(self.parents[-1].child(self.parents[-1].childCount() - 1))
self.indentations.append(position)
else:
while position < self.indentations[-1] and len(self.parents) > 0:
self.parents.pop()
self.indentations.pop()
parent = self.parents[-1]
parent.insertChildren(parent.childCount(), 1, parent.columnCount())
parent.child(parent.childCount() - 1).setData(0, dict_keys)
if type(dict_values) != dict:
parent.child(parent.childCount() - 1).setData(1, str(dict_values))
self.createData(dict_values, indent)
def index(self, row, column, index=QModelIndex()):
""" Returns the index of the item in the model specified by the given row, column and parent index """
if not self.hasIndex(row, column, index):
return QModelIndex()
if not index.isValid():
item = self.rootItem
else:
item = index.internalPointer()
child = item.child(row)
if child:
return self.createIndex(row, column, child)
return QModelIndex()
def parent(self, index):
""" Returns the parent of the model item with the given index
If the item has no parent, an invalid QModelIndex is returned """
if not index.isValid():
return QModelIndex()
item = index.internalPointer()
if not item:
return QModelIndex()
parent = item.parentItem
if parent == self.rootItem:
return QModelIndex()
else:
return self.createIndex(parent.childNumber(), 0, parent)
def rowCount(self, index=QModelIndex()):
""" Returns the number of rows under the given parent
When the parent is valid it means that rowCount is returning the number of children of parent """
if index.isValid():
parent = index.internalPointer()
else:
parent = self.rootItem
return parent.childCount()
def columnCount(self, index=QModelIndex()):
""" Returns the number of columns for the children of the given parent """
return self.rootItem.columnCount()
def data(self, index, role=Qt.DisplayRole):
""" Returns the data stored under the given role for the item referred to by the index """
if index.isValid() and role == Qt.DisplayRole:
return index.internalPointer().data(index.column())
elif not index.isValid():
return self.rootItem.data(index.column())
def headerData(self, section, orientation, role=Qt.DisplayRole):
""" Returns the data for the given role and section in the header with the specified orientation """
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.rootItem.data(section)
class TreeNode(object):
def __init__(self, data, parent=None):
self.parentItem = parent
self.itemData = data
self.children = []
def child(self, row):
return self.children[row]
def childCount(self):
return len(self.children)
def childNumber(self):
if self.parentItem is not None:
return self.parentItem.children.index(self)
def columnCount(self):
return len(self.itemData)
def data(self, column):
return self.itemData[column]
def insertChildren(self, position, count, columns):
if position < 0 or position > len(self.children):
return False
for row in range(count):
data = [v for v in range(columns)]
item = TreeNode(data, self)
self.children.insert(position, item)
def parent(self):
return self.parentItem
def setData(self, column, value):
if column < 0 or column >= len(self.itemData):
return False
self.itemData[column] = value
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle("plastique") # ("cleanlooks")
form = GUIWindow()
form.show()
sys.exit(app.exec_())
#/usr/bin/env python
#-*-编码:utf-8-*-
导入系统
从PySide2.qtwidts导入QApplication、QWidget、QGroupBox、QHBoxLayout、QVBoxLayout、QTreeView
从PySide2.QtCore导入Qt、qabstractemmodel、QModelIndex
类GUI窗口(QWidget):
def uuu init uuu(self,parent=None):
超级(GUIWindow,self)。\uuuu init\uuuu(父级)
“安装界面”
self.setWindowTitle(“来自字典的QTreeView”)
groupbox_model=QGroupBox('TreeView')#为模型创建一个分组框
hbox_model=QHBoxLayout()#为模型创建水平布局
vbox=QVBoxLayout()#为模型水平布局创建垂直布局
tree_view=QTreeView()#实例化视图
headers=[“字典键”,“字典值”]
tree={'Root':{“Level_1”:{“Item_1”:1.10,“Item_2”:1.20,“Item_3”:1.30},
“二级”:{“一级以下”:
{“次级项目1”:2.11,“次级项目2”:2.12,“次级项目3”:2.13},
“次级2”:
{“次级项目1”:2.21,“次级项目2”:2.22,
“次级项目3”:2.23},
“第三级”:{“第1项”:3.10,“第2项”:3.20,“第3项”:3.30}}
#树立榜样
模型=树模型(标题、树)
树视图.集合模型(模型)
树视图。expandAll()
树视图。调整ColumnToContent的大小(0)
hbox_model.addWidget(树视图)#将小部件添加到模型水平布局中
groupbox_模型。setLayout(hbox_模型)#将hbox_模型添加到group box的布局中
vbox.addWidget(groupbox#U模型)#将groupbox元素添加到vbox
self.setLayout(vbox)
类树模型(QAbstractItemModel):
def uuu init uuuu(self,header,data,parent=None):
super(树模型,self)。\uuuu init\uuuuu(父级)
“”“子类化标准接口项模型必须使用和
正在实现索引()、父项()、行计数()、列计数()和数据()
rootData=[标头中标头的标头]
self.rootItem=TreeNode(rootData)
缩进=-1
self.parents=[self.rootItem]
self.indentations=[0]
self.createData(数据,缩进)
def createData(自身、数据、缩进):
如果类型(数据)=dict:
缩进+=1
位置=4*缩进
对于dict_键,data.items()中的dict_值:
如果位置>自缩进[-1]:
如果self.parents[-1].childCount()>0:
self.parents.append(self.parents[-1].child(self.parents[-1].childCount()-1))
self.indentations.append(位置)
其他:
而位置0:
self.parents.pop()
self.indentations.pop()
父母=自己。父母[-1]
parent.insertChildren(parent.childCount(),1,parent.columnCount())
parent.child(parent.childCount()-1).setData(0,dict_键)
如果类型(dict_值)!=格言:
parent.child(parent.childCount()-1).setData(1,str(dict_值))
self.createData(dict_值,缩进)
def索引(self,row,column,index=QModelIndex()):
“”“返回给定行、列和父索引指定的模型中项的索引”“”
如果不是self.hasIndex(行、列、索引):
返回QModelIndex()
如果不是index.isValid():
item=self.rootItem
其他:
item=index.internalPointer()
子项=项。子项(行)
如果是儿童:
返回self.createIndex(行、列、子级)
返回QModelIndex()
def父级(自我,索引):
“”“返回具有给定索引的模型项的父项。”
如果该项没有父项,则返回无效的QModelIndex“”
如果不是index.isValid():
返回QModelIndex()
item=index.internalPointer()
如果不是项目:
返回QModelIndex()
父项=项。父项
如果父项==self.rootItem:
返回QModelIndex()
其他:
返回self.createIndex(parent.childNumber(),0,parent)
def行数(self,index=QModelIndex()):
“”“返回给定父项下的行数
当父级有效时,表示rowCount返回父级“”的子级数
如果index.isValid():
parent=index.internalPointer()
其他:
父项=self.rootItem
返回parent.childCount()
def columnCount(self,index=QModelIndex()):
“”“返回给定父级的子级的列数”“”
返回self.rootItem.columnCount()
def数据(self,index,role=Qt.DisplayRole):
“”“为索引引用的项返回存储在给定角色下的数据”“”
如果index.isValid()和role==Qt.DisplayRole:
返回index.internalPointer().data(index.column())
elif不是索引。isValid():
返回self.rootItem.data(index.column())
def headerData(自身、部分、方向、角色=Qt.DisplayRole):
“”“返回标头中具有指定方向的给定角色和节的数据”