0

QTreeWidgetItem を特定のインデックスに正しく挿入できません。この場合、ツリーからすべての QTreeWidgetItem を削除し、それらの Date オブジェクトでカスタム ソートを実行してから、それらを QTreeWidget に挿入し直しています。

ただし、(一度に 1 つでも) 挿入すると、QTreeWidgetItem は正しい場所に挿入されません。

以下のコードが出力されます。

インデックス 0: 0

インデックス 0: 1 インデックス 1: 0

インデックス 0: 2 インデックス 1: 1 インデックス 2: 0

インデックス 0: 3 インデックス 1: 2 インデックス 2: 0インデックス 3: 1

インデックス 0: 4 インデックス 1: 2 インデックス 2: 0インデックス 3: 1インデックス 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])
4

2 に答える 2

2

ツリーを補充する必要なく、カスタム ソートを実行できます。アイテムの「less」演算子をオーバーロードするだけです。QT は、アイテムの

virtual QVariant data ( int column, int role ) const

アイテムを作成するとき、表示するアイテムのコンストラクターに文字列を提供します。この文字列は data(.., QtCore.Qt.EditRole) に配置されるため、データをコンストラクターに渡すのと同じことは、次のようにデータを設定することです。

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

内部的には、データは単なる配列であり、好きなものを配置でき、そのインデックスはロール (Qt.EditRole は 2、Qt.ToolTipRole は 3 など) であるため、いくつかのロールにデータを含め、比較を伝えます。演算子を使用してこれらの値を比較し、たとえば ValueRole を設定するときに setData に DisplayRole を設定するよう伝えます。サンプルは次のとおりです。

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()

私はテストしました、それはうまくいきます。もちろん、ダックタイピングがあったため、継承を回避してltを直接オーバーライドできます。 UserRole 自体を使用してデータを保持し、データを setData(col, role, val) で直接表示するか、編集/表示でテキストのみを保持することさえできます比較するときだけdatetimeに変換しますが、それは醜いようです。data() には QVariant が含まれていることに注意してください。データを設定すると、py オブジェクトが自動的に変換され、 toPyObject() を呼び出して値を元に戻す必要があります。

于 2010-03-26T15:16:17.940 に答える
2

問題はコードの別の場所にあるはずです。アイテムを適切に削除していない可能性がありますか?以下が機能するため:

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_()
于 2010-03-26T18:11:34.623 に答える