Pergunta

Não consigo inserir corretamente um QtreeWidgetItEm em um índice específico, neste caso estou removendo todos os QtreewidgetItems da árvore, fazendo uma classificação personalizada em seus objetos de data e depois os inserindo de volta no QtreeWidget.

No entanto, ao inserir (mesmo um de cada vez), o QtreeWidgetItEM não é inserido no local correto.

O código abaixo imprime:

ÍNDICE 0: 0

ÍNDICE 0: 1 ÍNDICE 1: 0

ÍNDICE 0: 2 ÍNDICE 1: 1 ÍNDICE 2: 0

ÍNDICE 0: 3 ÍNDICE 1: 2 ÍNDICE 2: 0 ÍNDICE 3: 1

ÍNDICE 0: 4 ÍNDICE 1: 2 ÍNDICE 2: 0 ÍNDICE 3: 1 ÍNDICE 4: 3

print 'index 0: ', self.indexOfTopLevelItem(childrenList[0])

self.insertTopLevelItem(0, childrenList[1])

print 'index 0: ', self.indexOfTopLevelItem(childrenList[0]), ' index 1: ',\
    self.indexOfTopLevelItem(childrenList[1])

self.insertTopLevelItem(0, childrenList[2])

print 'index 0: ', self.indexOfTopLevelItem(childrenList[0]), ' index 1: ',\
    self.indexOfTopLevelItem(childrenList[1]), ' index 2: ', \
    self.indexOfTopLevelItem(childrenList[2])

self.insertTopLevelItem(0, childrenList[3])

print 'index 0: ', self.indexOfTopLevelItem(childrenList[0]), ' index 1: ',\
    self.indexOfTopLevelItem(childrenList[1]), ' index 2: ',\
    self.indexOfTopLevelItem(childrenList[2]), 'index 3: ',\
    self.indexOfTopLevelItem(childrenList[3])

self.insertTopLevelItem(0, childrenList[4])

print 'index 0: ', self.indexOfTopLevelItem(childrenList[0]),\
    ' index 1: ', self.indexOfTopLevelItem(childrenList[1]),\
    ' index 2: ', self.indexOfTopLevelItem(childrenList[2]),\
    'index 3: ', self.indexOfTopLevelItem(childrenList[3]),\
    'index 4: ', self.indexOfTopLevelItem(childrenList[4])
Foi útil?

Solução

Você pode fazer sua classificação personalizada sem a necessidade de reabastecer a árvore. Você só precisa sobrecarregar o operador 'menos' do item. Observe que o QT descobre, o que desenhar na célula, que tamanho deveria ter, que texto deve conter, olhando no item

virtual QVariant data ( int column, int role ) const

Ao criar um item, você fornece alguma string para construtor para o item mostrar. Esta string é colocada em dados (.., qtcore.qt.editrole); portanto, o equivalente a transmitir dados para a Constutor é definir dados com:

virtual void setData ( int column, int role, const QVariant & value)

Internamente, os dados são apenas uma matriz, você pode colocar qualquer coisa jovem querer e os índices são papéis (qt.editrole é 2, qt.ToolTiprole é 3 etc.), por isso apenas deixamos alguma função conter nossos dados, informando a comparação Operador para comparar esses valores e informar o SetData Set DisplayRole quando definirmos nosso valor, digamos, valuerole. Aqui está a amostra:

class TreeItem(QtGui.QTreeWidgetItem):

    PythonValueRole = QtCore.Qt.UserRole

    #values are list of python objects, that have __str__ and can be compared
    def __init__(self, tree, values):
        QtGui.QTreeWidgetItem.__init__(self, tree)
        i = 0
        for v in values:
            self.setData(i, TreeItem.PythonValueRole, v)
            i += 1

    #overridden to simplify data assigning. When called with PythonValueRole, passes
    #that object's string representation to DisplayRole and EditRole
    def setData(self, col, role, value):
        if role == TreeItem.PythonValueRole:
            QtGui.QTreeWidgetItem.setData(self, col, TreeItem.PythonValueRole, value)
            # sets DisplayRole and EditRole
            QtGui.QTreeWidgetItem.setData(self, col, QtCore.Qt.EditRole, str(value)) 
            QtGui.QTreeWidgetItem.setData(self, col, QtCore.Qt.DisplayRole, str(value))
        else:
            QtGui.QTreeWidgetItem.setData(self, col, role, value)

    def __lt__(self, other):
        c = self.treeWidget().sortColumn()
        return self.data(c, TreeItem.PythonValueRole).toPyObject() < 
               other.data(c, TreeItem.PythonValueRole).toPyObject()

Eu testei, funciona bem. De Cource, você pode evitar herança e substituir lt Diretamente, como tínhamos digitação de pato, usamos a própria Userrole para manter seus dados e definir dados exibidos diretamente com o SetData (col, função, Val) ou até mesmo manter o texto na função de edição/exibição e convertê -lo apenas no DateTime enquanto comparava, Mas parece feio. Observe que Data () contém QVariant. Quando você define dados, seu objeto Py se converte automatizando automaticamente e você precisa ligar para topyObject () para obter seu valor de volta como era.

Outras dicas

O problema deve estar em outro lugar do seu código. Talvez você não esteja removendo os itens corretamente? Porque os seguintes trabalhos:

import sys

from PyQt4.QtGui import *
from PyQt4.QtCore import *

app = QApplication(sys.argv)

tree = QTreeWidget()
items = [QTreeWidgetItem(['index %i' % i]) for i in range(5)]

for item in items:
    tree.insertTopLevelItem(0, item)

print 'indexes: '
for item in items:
    print tree.indexOfTopLevelItem(item),

tree.show()

app.exec_()
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top