Как добавить дочернюю строку в строку QTreeView, найденную по определенному значению столбца? - PullRequest
0 голосов
/ 07 декабря 2018

Следующий пример приложения предназначен для отображения QTreeView, заполнения его 4 строками и добавления еще 12 строк, случайным образом распределяющих их как дочерние элементы между первоначально добавленными 4.Родители должны быть выбраны по значениям их столбца UUID (который не может быть первым столбцом в строке).Все UUID уникальны.

Я пытаюсь использовать self.findItems(parent_uuid, Qt.MatchExactly, 1) (где parent_uuid: str - это значение идентификатора выбранного родителя, а 1 - индекс столбца, в котором хранятся идентификаторы), чтобы найти нужного родителя.строка, но возвращаемый результат выглядит как 1-элементный список QStandardItem, содержащий UUID.

Как мне изменить код для достижения желаемого поведения?

Я использую Python 3.7 и Qt5.11.Код пользовательского интерфейса генерируется с помощью pyuic5 из XML-файла пользовательского интерфейса Qt, созданного с помощью 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()

1 Ответ

0 голосов
/ 07 декабря 2018

findItems возвращает список элементов, которые соответствуют запросу, поэтому в вашем случае вам просто нужно получить первый элемент, но вы не можете добавить элементы, так как вы должны взять в качестве родительского элемента в столбце 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)

enter image description here

...