2017-08-13 2 views
0

J'utilise un QListWidget qui affiche simplement une liste d'objets. J'autorise l'utilisateur à réorganiser ces éléments via un glisser-déposer interne. Tout fonctionne, mais je dois maintenant ajouter une vérification lorsque l'utilisateur essaie de supprimer (réorganiser) et si la vérification échoue, rétablir l'ordre d'origine par programmation. Voici ce que j'ai:Comment faire pour annuler une opération glisser-déposer par programme dans un QListWidget?

class SequenceControl(QListWidget): 
    def __init__(self, parent = None): 
     super(SequenceControl, self).__init__(parent) 

     self.initialIndex = 0 
     self.selectedObject = None 
     self.setAcceptDrops(True) 
     self.setDragEnabled(True) 
     self.setDragDropMode(QAbstractItemView.InternalMove) 


    def dragEnterEvent(self, event): 
     super(SequenceControl, self).dragEnterEvent(event) 

     self.selectedObject = self.currentItem() 
     self.initialIndex = self.currentRow() 

    def dropEvent(self, event): 
     super(SequenceControl, self).dropEvent(event) 

     # Some logic here (not shown) to see if the drop is not 
     # allowed. Assume it isn't: 
     warningDialog = MyWarningDialog(self.parent) 
     ProceedAnyway = warningDialog.exec_() 

     if ProceedAnyway: 
      # Do stuff... 
     else: 
      # Here's the problem. I need to place the item being dropped 
      # back in its initial pre-drag/drop location. The following 
      # naïve attempt doesn't work: 
      self.insertItem(self.initialIndex, self.selectedObject) 

Ce qui précède est certainement mal (je crois) parce qu'il peut dupliquer l'élément. Mais mis à part cela, le problème est qu'il semble n'avoir aucun effet. Je pense que l'événement drop prévaut sur tout ce que je fais en termes de réorganisation. Mais c'est juste une théorie. Est-ce que quelqu'un sait la bonne façon de faire cela?

Répondre

1

Pour annuler la modification, nous devons d'abord supprimer l'élément cible, pour cela, nous utilisons takeItem() qui, en plus de supprimer il renverra l'élément, puis l'insérer dans la position source à l'aide de la fonction insertItem().

class SequenceControl(QListWidget): 
    def __init__(self, parent=None): 
     super(SequenceControl, self).__init__(parent) 

     self.fromPos = None 
     self.setAcceptDrops(True) 
     self.setDragEnabled(True) 
     self.setDragDropMode(QAbstractItemView.InternalMove) 

    def dragEnterEvent(self, event): 
     super(SequenceControl, self).dragEnterEvent(event) 
     self.fromPos = self.currentRow() 

    def dropEvent(self, event): 
     super(SequenceControl, self).dropEvent(event) 

     reply = QMessageBox.question(None, "Revert to Drag and Drop", 
            "Do you want to keep the change?", 
            QMessageBox.Yes | QMessageBox.No) 
     if reply == QMessageBox.Yes: 
      print("Do stuff...") 
     else: 
      currentItem = self.takeItem(self.currentRow()) 
      self.insertItem(self.fromPos, currentItem)