qtreewidget inserttoplevelitem-ツリーに正確に表示されていないと与えられたインデックス?
-
22-09-2019 - |
質問
特定のインデックスにqtreewidgetitemを適切に挿入することはできません。この場合、ツリーからすべてのqtrewidgetitemsを削除し、日付オブジェクトでカスタムソートを実行し、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])
解決
ツリーを補充する必要なく、カスタムソートを実行できます。アイテムの「少ない」オペレーターをオーバーロードするだけです。 QTは、アイテムを見ることによって、セルに何を描くか、どのようなサイズ、どのようなテキストを含めるべきか、どのテキストを含めるべきかを理解していることに注意してください
virtual QVariant data ( int column, int role ) const
アイテムを作成するとき、アイテムを表示するためのコンストラクターに文字列を提供します。この文字列はデータ(..、qtcore.qt.editrole)に配置されるため、データを渡すデータに相当するのは、次のことをデータを設定することです。
virtual void setData ( int column, int role, const QVariant & value)
内部的には、データは単なる配列であり、必要なものをすべて配置でき、そのインデックスは役割です(qt.editroleは2、qt.tooltiproleは3など)。これらの値を比較し、SetData Set DisplayRoleを設定したときに、Valueroleを設定したときにオペレーターを伝えます。これがサンプルです:
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 直接、ダックタイピングがあったので、Usererole自体を使用してデータを保持し、データはSetData(col、role、val)で直接表示します。または、編集/表示の役割のテキストのみを保持し、比較してのみデータを変換します。しかし、それは醜いようです。 data()にはqvariantが含まれていることに注意してください。データを設定すると、Pyオブジェクトは自動的に変換され、TopyObject()を呼び出して価値を取り戻す必要があります。
他のヒント
問題はあなたのコードの他の場所でなければなりません。たぶんあなたはアイテムを適切に削除していませんか?次の動作があるため:
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_()