如何将 child 行添加到由特定列值找到的 QTreeView 行?
How to add a child row to a QTreeView row found by a specific column value?
以下示例应用程序旨在显示 QTreeView,用 4 行填充它并添加 12 行,将它们随机分布为 children 在最初添加的 4 行之间。 parents 必须通过它们的 UUID 列(不能是一行中的第一列)的值来选择。所有的 UUID 都是唯一的。
我正在尝试使用 self.findItems(parent_uuid, Qt.MatchExactly, 1)
(其中 parent_uuid: str
是选择的 parent id 值,1 是存储 id 的列的索引)找到所需的parent 行,但返回的结果似乎只是一个包含 UUID.
的 QStandardItem 的 1 元素列表
如何更改代码以实现所需的行为?
我使用 Python 3.7 和 Qt 5.11。 UI 代码是用 pyuic5 从 Qt UI XML 文件中生成的,该文件是用 QtDesigner 生成的。
完整的应用程序源代码:
#!/usr/bin/env python
import random
import sys
import uuid
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QApplication, QMainWindow
LETTERS = 'abcdefghijklm'
def main():
application = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(application.exec_())
class TreeViewModel(QStandardItemModel):
def __init__(self, *args, **kwargs):
super(TreeViewModel, self).__init__(*args, **kwargs)
def populate(self): # This is where the work is done
self.clear()
self.setHorizontalHeaderLabels(['Name', 'UUID', 'Attr1'])
parents_uuids = []
for i in range(16):
name = random.choice(LETTERS) \
+ random.choice(LETTERS) \
+ random.choice(LETTERS)
uuid_ = str(uuid.uuid4())
attr1 = str(random.random())
row = [QStandardItem(name),
QStandardItem(uuid_),
QStandardItem(attr1)]
if len(parents_uuids) < 4:
self.appendRow(row)
parents_uuids.append(uuid_)
else:
# TODO: Fix this else clause so it'd make the new row a child
# The parent row must be found by its UUID column str value
parent_uuid = random.choice(parents_uuids)
parent = self.findItems(parent_uuid, Qt.MatchExactly, 1)
parent.appendRow(row) # Error
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.actionPopulateTree.triggered \
.connect(self.on_action_populate_tree)
self.ui.treeView.setModel(TreeViewModel(self))
def on_action_populate_tree(self):
self.ui.treeView.model().populate()
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(320, 240)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.treeView = QtWidgets.QTreeView(self.centralwidget)
self.treeView.setObjectName("treeView")
self.gridLayout.addWidget(self.treeView, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.actionPopulateTree = QtWidgets.QAction(MainWindow)
self.actionPopulateTree.setObjectName("actionPopulateTree")
self.toolBar.addAction(self.actionPopulateTree)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.actionPopulateTree.setText(_translate("MainWindow", "PopulateTree"))
if __name__ == "__main__":
main()
findItems returns 与搜索匹配的项目列表,因此在您的情况下,您只需要获取第一个项目但仍然无法添加项目,因为您必须将项目作为父项目第 0 列,但您已从第 1 列获得该项目,因此其他逻辑部分将获得该项目:
parent_uuid = random.choice(parents_uuids)
items = self.findItems(parent_uuid, Qt.MatchExactly, 1)
if items:
ix = self.indexFromItem(items[0])
ix_col_0 = self.sibling(ix.row(), 0, ix)
it_col_0 = self.itemFromIndex(ix_col_0)
it_col_0.appendRow(row)
以下示例应用程序旨在显示 QTreeView,用 4 行填充它并添加 12 行,将它们随机分布为 children 在最初添加的 4 行之间。 parents 必须通过它们的 UUID 列(不能是一行中的第一列)的值来选择。所有的 UUID 都是唯一的。
我正在尝试使用 self.findItems(parent_uuid, Qt.MatchExactly, 1)
(其中 parent_uuid: str
是选择的 parent id 值,1 是存储 id 的列的索引)找到所需的parent 行,但返回的结果似乎只是一个包含 UUID.
如何更改代码以实现所需的行为?
我使用 Python 3.7 和 Qt 5.11。 UI 代码是用 pyuic5 从 Qt UI XML 文件中生成的,该文件是用 QtDesigner 生成的。
完整的应用程序源代码:
#!/usr/bin/env python
import random
import sys
import uuid
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QApplication, QMainWindow
LETTERS = 'abcdefghijklm'
def main():
application = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(application.exec_())
class TreeViewModel(QStandardItemModel):
def __init__(self, *args, **kwargs):
super(TreeViewModel, self).__init__(*args, **kwargs)
def populate(self): # This is where the work is done
self.clear()
self.setHorizontalHeaderLabels(['Name', 'UUID', 'Attr1'])
parents_uuids = []
for i in range(16):
name = random.choice(LETTERS) \
+ random.choice(LETTERS) \
+ random.choice(LETTERS)
uuid_ = str(uuid.uuid4())
attr1 = str(random.random())
row = [QStandardItem(name),
QStandardItem(uuid_),
QStandardItem(attr1)]
if len(parents_uuids) < 4:
self.appendRow(row)
parents_uuids.append(uuid_)
else:
# TODO: Fix this else clause so it'd make the new row a child
# The parent row must be found by its UUID column str value
parent_uuid = random.choice(parents_uuids)
parent = self.findItems(parent_uuid, Qt.MatchExactly, 1)
parent.appendRow(row) # Error
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.actionPopulateTree.triggered \
.connect(self.on_action_populate_tree)
self.ui.treeView.setModel(TreeViewModel(self))
def on_action_populate_tree(self):
self.ui.treeView.model().populate()
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(320, 240)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.treeView = QtWidgets.QTreeView(self.centralwidget)
self.treeView.setObjectName("treeView")
self.gridLayout.addWidget(self.treeView, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.actionPopulateTree = QtWidgets.QAction(MainWindow)
self.actionPopulateTree.setObjectName("actionPopulateTree")
self.toolBar.addAction(self.actionPopulateTree)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.actionPopulateTree.setText(_translate("MainWindow", "PopulateTree"))
if __name__ == "__main__":
main()
findItems returns 与搜索匹配的项目列表,因此在您的情况下,您只需要获取第一个项目但仍然无法添加项目,因为您必须将项目作为父项目第 0 列,但您已从第 1 列获得该项目,因此其他逻辑部分将获得该项目:
parent_uuid = random.choice(parents_uuids)
items = self.findItems(parent_uuid, Qt.MatchExactly, 1)
if items:
ix = self.indexFromItem(items[0])
ix_col_0 = self.sibling(ix.row(), 0, ix)
it_col_0 = self.itemFromIndex(ix_col_0)
it_col_0.appendRow(row)