NARCISO, Rui wrote:
It worked nicely up to the sorting part.
And if th euser sorts the data himself, then eveything is ok.
It's just when I try to implement default sorting that that fails.
Maybe I can pick up on a signal telling that sorting is in progress to override
this behaviour in the rowsInserted function...
-----Message d'origine-----
De : Baz Walter [mailto:[email protected]]
Envoyé : vendredi 11 décembre 2009 21:46
À : NARCISO, Rui
Cc : PyQt (E-mail)
Objet : Re: [PyQt] Drag & Drop with QTreeWidget
NARCISO, Rui wrote:
Hi again
Your approach worked nicely but when I tried to enable sorting using:
self.setSortingEnabled(True)
self.sortByColumn(0, QtCore.Qt.AscendingOrder)
I get a segmentation fault.
If i disable the sortByColumn then it works.
How then to set the sorting using column 0 by default ?
actually, i now think my approach was too crude. the trouble with using
rowsInserted is that it is called every time items are added or moved
(or sorted).
what is really needed is a way to add special handling only for dropped
items. unfortunately, there does not appear to be an obvious way to
detect what items were dropped and where. so i think the only reliable
way to get the behaviour you want is to reimplement qtreewidget's drop
event handling (which is probably doable, but not easy).
i had another look at reimplementing qtreewidget's drop event handling
and it is in fact much easier than i thought. the code below simply
reproduces the current behaviour (it's mostly a port of the qt source).
hopefully it should not be too difficult to see how to adapt the code in
the moveSelection function to get whatever alternate behaviours you
want. (note that this example assumes internal moves only).
import sys
from PyQt4 import QtGui, QtCore
class TreeWidget(QtGui.QTreeWidget):
def __init__(self, parent=None):
QtGui.QTreeWidget.__init__(self, parent)
self.header().setHidden(True)
self.setSelectionMode(self.ExtendedSelection)
self.setDragDropMode(self.InternalMove)
self.setDragEnabled(True)
self.setDropIndicatorShown(True)
def add(num):
item = QtGui.QTreeWidgetItem(
self, QtCore.QStringList('Item(%i)' % num))
for i in xrange(1, 4):
QtGui.QTreeWidgetItem(
item, QtCore.QStringList('Child(%i,%i)' % (num, i)))
item.setExpanded(True)
for i in xrange(1, 3):
add(i)
def dropEvent(self, event):
if event.source() == self:
QtGui.QAbstractItemView.dropEvent(self, event)
def dropMimeData(self, parent, row, data, action):
if action == QtCore.Qt.MoveAction:
return self.moveSelection(parent, row)
return False
def moveSelection(self, parent, position):
# save the selected items
selection = [QtCore.QPersistentModelIndex(i)
for i in self.selectedIndexes()]
parent_index = self.indexFromItem(parent)
if parent_index in selection:
return False
# save the drop location in case it gets moved
target = self.model().index(position, 0, parent_index).row()
if target < 0:
target = position
# remove the selected items
taken = []
for index in reversed(selection):
item = self.itemFromIndex(QtCore.QModelIndex(index))
if item is None or item.parent() is None:
taken.append(self.takeTopLevelItem(index.row()))
else:
taken.append(item.parent().takeChild(index.row()))
# insert the selected items at their new positions
while taken:
if position == -1:
# append the items if position not specified
if parent_index.isValid():
parent.insertChild(
parent.childCount(), taken.pop(0))
else:
self.insertTopLevelItem(
self.topLevelItemCount(), taken.pop(0))
else:
# insert the items at the specified position
if parent_index.isValid():
parent.insertChild(min(target,
parent.childCount()), taken.pop(0))
else:
self.insertTopLevelItem(min(target,
self.topLevelItemCount()), taken.pop(0))
return True
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
tree = TreeWidget()
tree.resize(200, 300)
tree.move(300, 300)
tree.show()
sys.exit(app.exec_())
_______________________________________________
PyQt mailing list [email protected]
http://www.riverbankcomputing.com/mailman/listinfo/pyqt