Faites glisser et déposez les lignes à l'intérieur de QTableWidget
Objectif
Mon but est d'avoir un QTableWidget
dans laquelle l'utilisateur peut glisser/déposer les lignes en interne. Qui est, l'utilisateur peut faire glisser et de déposer une ligne entière, en le déplaçant vers le haut ou vers le bas dans le tableau à un autre emplacement dans l'entre deux autres lignes. Le but est illustré dans cette figure:
Ce que j'ai essayé, et ce qui se passe
Une fois que j'ai rempli un QTableWidget
avec les données, je définissez ses propriétés comme suit:
table.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
#select one row at a time
table.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
Même code rend QListWidget
se comportent bien: lorsque vous déplacez un élément interne, il est tombé entre deux éléments de la liste, et le reste des éléments arrangent d'elles-mêmes, d'une manière raisonnable, en l'absence de données écrasées (en d'autres termes, le point de vue des actes comme la figure ci-dessus, mais c'est une liste).
En revanche, dans un tableau modifié avec le code ci-dessus, les choses ne fonctionnent pas comme prévu. La figure suivante montre ce qui se passe réellement:
Dans les mots: lors de la ligne je est tombé, cette ligne devient vide dans le tableau. De plus, si je tombe accidentellement ligne je sur la ligne j (au lieu de l'espace entre deux lignes), les données à partir de la ligne je remplace les données dans la ligne j. C'est, dans ce cas malheureux, en plus de la ligne je devenir vide, ligne j est écrasé.
Remarque j'ai aussi essayé d'ajouter table.setDragDropOverwriteMode(False)
mais il n'a pas changé le comportement.
Une voie à suivre?
Ce rapport de bug peut inclure une solution possible en C++: il semble qu'ils réimplémentée dropEvent
pour QTableWidget
, mais je ne suis pas sûr de savoir comment proprement port de Python.
Contenu connexe:
- La réorganisation des éléments dans un QTreeWidget avec un Glisser-Déposer dans PyQt
- QT: interne glisser-déposer de lignes dans QTableView, que de modifier l'ordre des lignes dans QTableModel
- http://www.qtcentre.org/threads/35113-QTableWidget-dropping-between-the-rows-shall-insert-the-item
- qt: pyqt: QTreeView interne de glisser et de déposer près de de travail... l'élément glissé disparaît
- Comment drag & drop lignes dans QTableWidget
- QListWidget faites glisser et déposer des éléments de disparaître de la liste sur Symbian
- QTableWidget Interne De Glisser-Déplacer Toute La Ligne
OriginalL'auteur neuronet | 2014-10-07
Vous devez vous connecter pour publier un commentaire.
Cela semble très étrange comportement par défaut. De toute façon, suivant le code de la rapport de bug lié à, j'ai porté avec succès quelque chose de PyQt. Il peut, ou peut ne pas être aussi robuste que ce code, mais il semble au moins de travail pour le simple cas de test que vous fournissez dans vos captures d'écran!
Les éventuels problèmes avec les dessous de la mise en œuvre sont:
La ligne sélectionnée n'a pas suivi le glisser-déposer (donc, si vous déplacez la troisième rangée, troisième rangée, reste sélectionné après le déménagement). Ce n'est probablement pas trop difficile à corriger!
Il pourrait ne pas fonctionner pour les lignes avec les lignes enfants. Je ne suis même pas sûr si un
QTableWidgetItem
peut avoir des enfants, il est peut-être bien.Je n'ai pas testé avec la sélection de plusieurs lignes, mais je pense que cela devrait fonctionner
Pour une raison que je n'ai pas eu à supprimer la ligne qui a été déplacé, malgré l'insertion d'une nouvelle ligne dans la table. Cela semble très étrange pour moi. Il semble presque comme l'insertion d'une ligne n'importe où, mais la fin ne pas augmenter le
rowCount()
de la table.Ma mise en œuvre de
GetSelectedRowsFast
est un peu différente de la leur. Il peut ne pas être rapide, et pourrait potentiellement avoir quelques bugs (je ne vérifie pas si les éléments sont activés ou sélectionnable) comme ils l'ont fait. Ce serait aussi facile à corriger je pense, mais est seulement un problème si vous désactivez une ligne est sélectionnée et que quelqu'un effectue ensuite un glisser/déposer. Dans cette situation, je pense que la meilleure solution pourrait être de désélectionner les lignes qu'ils ont été désactivés, mais cela dépend de ce que vous faites avec elle, je suppose!Si vous avez été en utilisant ce code dans un environnement de production, vous aurez probablement envie d'aller avec une belle dent de peigne et assurez-vous que tout avait un sens. Il y a très probablement des problèmes avec mon PyQt port, et, éventuellement, des problèmes avec le c++ de l'algorithme de mon port. Il n'est toutefois servir de preuve de ce que vous voulez peut être réalisé à l'aide d'un
QTableWidget
.Mise à jour: remarque: il existe un réponse supplémentaire ci-dessous pour PyQt5 qui résout également certaines des préoccupations que j'avais au-dessus. Vous pourriez vouloir vérifier!
Code:
merci beaucoup. votre lien avec le qt rapport de bogue site était tout ce que je cherchais. Il le fallait pour le c++, donc malheureusement, votre code n'est pas exactement ce dont j'avais besoin 🙂
OriginalL'auteur three_pineapples
Ici est une version révisée de trois-ananas réponse qui est conçu pour PyQt5 et Python 3. Il fixe également la multi-sélection par glisser-déposer et sélectionne à nouveau les lignes après le déménagement.
OriginalL'auteur Scott Maxwell
Je suis donc venu sur ce même problème récemment et j'ai distillé le code ci-dessus bloc vers le bas en quelque chose que je pense a tous le même comportement, mais est beaucoup plus succincte.
OriginalL'auteur Jesse C
Depuis je n'ai pas trouvé la bonne solution pour utiliser
C++
à l'aide de google, je veux ajouter le mien:OriginalL'auteur honiahaka10