IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PyQt Python Discussion :

[QListWidget] Ordre des items modifiés [QtGui]


Sujet :

PyQt Python

  1. #1
    Membre éclairé
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Par défaut [QListWidget] Ordre des items modifiés
    Bonjour,

    j'ai dans mon application un widget QListWidget contenant un certain nombre d'items, et l'utilisateur peut changer l'ordre de ces items en faisant un glisser-déposer avec la souris (il ne peut pas ajouter d'items provenant de l'extérieur, juste changer l'ordre de ceux qui y sont déjà).

    Je souhaiterais qu'une fonction soit appelée lorsque l'ordre des items a changé; ne trouvant pas de signal adapté à ce que je veux, je pensais utiliser le mouseReleaseEvent, mais je ne comprends pas comment l'utiliser pour qu'il s'active uniquement pour ce widget là...

    Quelqu'un peut-il m'aider?
    Merci d'avance.

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    Normalement tu devrais déjà pouvoir gérer ça avec dropEvent(), sinon peut-être que le signal indexesMoved() émit par ton QListWidget est suffisant.

    À tester, je ne l'ai jamais utilisé.

  3. #3
    Membre éclairé
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Par défaut
    Merci,
    le dropEvent est en effet mieux adapté, mais je n'arrive pas à m'en servir! Comment indiquer que je veux récupérer les dropEvents de mon widget QListWidget (créé sous QtDesigner)?

    Le signal IndexesMoved à l'air intéressant aussi, mais il faut utiliser un QModelIndexList et je ne sais pas trop ce que c'est... Mon QListWidget contient uniquement des objets de la classe QListWidgetItem.

  4. #4
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Ok, tu n'as pas sous-classé la QListWidget, alors à l'instanciation de ton interface tu peux "rediriger" les événements de ses widget vers tes fonctions dans ton main.

    Sera plus clair avec exemple
    Ton code principal:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
            # Tu crées ta main window    
            self.ui = Ui_MainWindow()
            self.ui.setupUi()
            # Puis tu rediriges
            self.ui.listWidget.dropEvent = self.dropEvent
            # Si tu en as d'autres tu changes le nom de la fonction appelée
            self.ui.tableWidget.dropEvent = self.drop_event
     
        def dropEvent(self, event):
            # Ici tu gères ton event
    Il est aussi possible de créer un filtre d'événements, mais c'est horrrriblement compliqué. (en fait j'aime pas)

  5. #5
    Membre éclairé
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Par défaut
    Merci,
    ça fonctionne bien, ma fonction est bien appelée lorsque je modifie l'ordre des items, cependant à chaque fois, l'item que j'ai déplacé disparaît du QListWidget! Pourquoi ce comportement?

  6. #6
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Comme cela c'est difficile à dire mais je soupçonne que tu n'as pas retourné l'event après l'avoir capté.

    En général comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        def dropEvent(self, event):
            # Ici tu gères ton event
            ...
            # Ensuite, tu renvoies
            self.ui.listWidget.dropEvent(self, event)

  7. #7
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Voilà un exemple très simple qui a l'air de faire ce qui est demandé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.7
     
    import sys
     
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        def __init__(self, parent=None):
            super(Fenetre, self).__init__(parent)
     
            self.setWindowTitle('Drag & Drop sur une QListWidget')
     
            self.lw = QtGui.QListWidget(self)
            self.datas = [u"toto1", u"toto2", u"toto3", u"toto4", u"toto5", u"toto6", u"toto7", u"toto8", u"toto9"]
            self.lw.addItems(self.datas)
     
            # détournement de la méthode dropEvent du QListWidget
            self.lw.dropEvent = self.dropEvent_lw
     
            # mode Drag&Drop sur le changement d'ordre (sans ajout ni effacement)
            self.lw.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
     
            posit = QtGui.QGridLayout()
            posit.addWidget(self.lw, 0, 0)
            self.setLayout(posit)
     
        def dropEvent_lw(self, event):
            """appelé à chaque modif d'ordre"""
            lw_item = self.lw.currentItem()
            lw_row = self.lw.row(lw_item)
            lw_data = lw_item.text()
     
            QtGui.QListWidget.dropEvent(self.lw, event)
     
            print u"dropEvent: l'item", lw_data, u"est passé de l'index", lw_row, u"à l'index", self.lw.row(self.lw.currentItem())
     
    #############################################################################
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        fen = Fenetre()
        fen.show()
        app.exec_()
    Permettre le changement d'ordre par drag&drop des éléments de la liste sans ajout ni effacement est facile puisqu'il suffit de le demander:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            self.lw.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
    Lors des modifications d'ordre par drag&drop, le dropEvent du QListWidget (donc ici le dropEvent_lw de la fenêtre) est appelé à chaque "drop", et le "print" intégré dans la méthode affiche, par exemple:

    dropEvent: l'item toto1 est passé de l'index 0 à l'index 8
    dropEvent: l'item toto1 est passé de l'index 8 à l'index 1
    dropEvent: l'item toto5 est passé de l'index 4 à l'index 7

  8. #8
    Membre éclairé
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Par défaut
    Merci ça fonctionne!
    J'avais déjà mis l'option "setDragDropMode" du QListWidget à "Internal Move",
    la "disparition" de l'élément que je déplaçait était en effet due au fait que je ne gérait pas bien l'event dans ma méthode.
    Par contre, la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.ui.listWidget.dropEvent(self, event)
    Ne fonctionne pas: cette commande appelle ma méthode récursivement à l'infini jusqu'à ce que le programme plante, alors qu'avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QtGui.QListWidget.dropEvent(self.ui.listWidget, event)
    j'ai bien le comportement attendu. Je ne comprends pas vraiment pourquoi, car les deux lignes ont l'air de faire la même chose, avec juste une syntaxe différente.

    Quoi qu'il en soit je met ce sujet comme résolu, merci VinsS et Tyrtamos pour votre aide!

  9. #9
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Effectivement, j'ai fais une confusion d'objet, sorry. Je suppose que tu as compris la raison de cette ligne qui consiste à retourner à Qt l'événement afin qu'il termine la tâche.

  10. #10
    Membre éclairé
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Par défaut
    Pas de souci oui je n'avais pas pensé au début à retourner l’événement, mais effectivement cette instruction paraît logique.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [QtGui] Ordre des items d'un QListWidget après un QDropEvent interne
    Par mokochan dans le forum PyQt
    Réponses: 10
    Dernier message: 08/08/2013, 10h12
  2. Report 6i en format texte : ordre des items
    Par reppier dans le forum Reports
    Réponses: 2
    Dernier message: 17/03/2010, 09h34
  3. [Joomla!] Ordre des items dans un menu
    Par pseudo88 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 30/09/2009, 17h28
  4. Changer l'ordre des Items de Menu.
    Par Ivynox dans le forum C#
    Réponses: 3
    Dernier message: 29/11/2007, 15h49
  5. [Portal 9iAS] : ordre des items dans une région
    Par melitta dans le forum Oracle
    Réponses: 8
    Dernier message: 21/10/2004, 14h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo