QTreeWidgetItem.insertChild с индексом 0

Я пытаюсь вставить новый дочерний элемент в верхнюю часть группы элементов. Кажется, что значение индекса не соблюдается, и элемент переходит в конец списка. Я искал и не нашел много совпадений для этого типа операции в QTreeWidgets. Я нашел простую программу для экспериментов:

"""
simple test of treewidget
"""
import sys
from PySide2 import QtWidgets

class Testclass():
    """
    test
    """
    def __init__(self):
        """
        test
        """
        app = QtWidgets.QApplication(sys.argv)
        window = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout(window)

        trw = QtWidgets.QTreeWidget()
        trw.setHeaderLabels(['Name', 'Date', 'Cost ($)'])
        chg = QtWidgets.QTreeWidgetItem(trw, ['carrots', None, None])
        datrows = [[None, '2020-00-00', '0.33'],
                   [None, '2020-00-00', '0.35'],
                   [None, '2020-00-00', '0.36']]
        for datrow in datrows:
            __ = QtWidgets.QTreeWidgetItem(chg, datrow)
        __ = chg.insertChild(0, QtWidgets.QTreeWidgetItem(chg, [None, '2020-00-00', '0.30']))


        layout.addWidget(trw)
        window.show()
        sys.exit(app.exec_())

Testclass()

Я играл с изменением родительских ссылок в элементе виджета дерева, изменяя индекс. Он добавил пустой элемент, а затем новый элемент в конце. Единственное, что я получил желаемый эффект, - это получить все элементы, добавить новый элемент в начало списка и перестроить дерево:

"""
simple test of treewidget
"""
import sys
from PySide2 import QtWidgets

class Testclass():
    """
    test
    """
    def __init__(self):
        """
        test
        """
        app = QtWidgets.QApplication(sys.argv)
        window = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout(window)

        trw = QtWidgets.QTreeWidget()
        trw.setHeaderLabels(['Name', 'Date', 'Cost ($)'])
        chg = QtWidgets.QTreeWidgetItem(trw, ['carrots', None, None])
        datrows = [[None, '2020-00-00', '0.33'],
                   [None, '2020-00-00', '0.35'],
                   [None, '2020-00-00', '0.36']]
        for datrow in datrows:
            __ = QtWidgets.QTreeWidgetItem(chg, datrow)
        chi_list = []
        for chgiix, chgii in enumerate(QtWidgets.QTreeWidgetItemIterator(chg)):
            chg_item = chgii.value()
            if chgiix:
                coldata = []
                for colix in range(chg_item.columnCount()):
                    coldata.append(chg_item.text(colix))
                chi_list.append(coldata)
        chi_list.insert(0, [None, '2020-00-00', '0.30'])
        _ = trw.takeTopLevelItem(0)
        chg = QtWidgets.QTreeWidgetItem(trw, ['carrots', None, None])
        for datrow in chi_list:
            __ = QtWidgets.QTreeWidgetItem(chg, datrow)
        print(chi_list)
        layout.addWidget(trw)
        window.show()
        sys.exit(app.exec_())

Testclass()

Есть лучший способ сделать это?


person EdLipson    schedule 18.10.2020    source источник


Ответы (1)


Проблема в том, что вы используете неправильный конструктор, например, в соответствии с вашим кодом вы используете этот конструктор:

QTreeWidgetItem :: QTreeWidgetItem (QTreeWidgetItem * parent, const QStringList & strings, int type = Type)
Создает элемент древовидного виджета и добавляет его к заданному родительскому элементу. Данный список строк будет установлен как текст элемента для каждого столбца в элементе.

То есть с QtWidgets.QTreeWidgetItem(chg, [None, '2020-00-00', '0.30']) вы уже добавляете элемент как дочерний элемент chg.

А затем, как указывает insertChild():

void QTreeWidgetItem :: insertChild (int index, QTreeWidgetItem * child)
Вставляет дочерний элемент по индексу в список дочерних элементов.

Если дочерний элемент уже был вставлен в другое место, он больше не будет вставлен.

(выделено мной)

То есть, будучи дочерним элементом chg, он не будет вставлен в начало.

Решение состоит не в передаче chg, а в использовании этого другого конструктора:

QTreeWidgetItem :: QTreeWidgetItem (const QStringList & strings, int type = Type)
Создает элемент древовидного виджета указанного типа. Элемент необходимо вставить в виджет-дерево. Данный список строк будет установлен как текст элемента для каждого столбца в элементе.

import sys
from PySide2 import QtWidgets


class Testclass:
    def __init__(self):
        app = QtWidgets.QApplication(sys.argv)
        window = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout(window)

        trw = QtWidgets.QTreeWidget()
        trw.setHeaderLabels(["Name", "Date", "Cost ($)"])
        chg = QtWidgets.QTreeWidgetItem(trw, ["carrots", None, None])
        datrows = [
            [None, "2020-00-00", "0.33"],
            [None, "2020-00-00", "0.35"],
            [None, "2020-00-00", "0.36"],
        ]
        for datrow in datrows:
            QtWidgets.QTreeWidgetItem(chg, datrow)
        chg.insertChild(0, QtWidgets.QTreeWidgetItem([None, "2020-00-00", "0.30"]))

        layout.addWidget(trw)
        window.show()
        sys.exit(app.exec_())


Testclass()
person eyllanesc    schedule 18.10.2020
comment
Спасибо. Я не проработал все разные конструкторы, не рассмотрел их / - person EdLipson; 18.10.2020