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 :

QTreeView / liste à plusieurs colonnes 1 niveau d'indentation


Sujet :

PyQt Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Membre associatif
    Inscrit en
    Juillet 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Membre associatif

    Informations forums :
    Inscription : Juillet 2014
    Messages : 21
    Points : 15
    Points
    15
    Par défaut QTreeView / liste à plusieurs colonnes 1 niveau d'indentation
    Bonjour,

    Ceci est mon premier message sur ce forum. D’habitude je trouve, mais là je suis juste épuisé de pas trouver ce que je veux :-(.

    Je souhaite faire passer des éléments d'une QTreeView A vers une QtreeView B. MAIS je ne veux qu'un seul niveau d'indentation, je ne veux pas d'enfant. Or avec le drag & drop je n'arrive pas à trouver d'option qui me permette de faire ça.

    Alors je me suis dit qu'il fallait que je fasse une fonction qui ramène au TopLevel tous les enfants de la liste si il y en a. Mais je n'y arrive pas, c'est la première fois que j'essaye d'utiliser QTreeView et c'est un cauchemard pour moi et je ne trouve pas beaucop d'exemples sur le sujet.

    Un petit coup de pouce serait le bienvenu ! :-)

    Voici la fonction proposée:

    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
     
    def move2top(self):
        a=self.treeWidget_3.topLevelItemCount()
        i=0
        while i < a:
            b = self.treeWidget_3.topLevelItem(i)
            c = b.childCount()
            j = c
            if c > 0:
                while j > 0:
                    d = self.treeWidget_3.topLevelItem(i).child(j)
                    item=QtGui.QTreeWidgetItem(d)
                    print item.text(0)
                    self.treeWidget_3.addTopLevelItem(item)
                    e=self.treeWidget_3.topLevelItemCount()
                    self.treeWidget_3.topLevelItem(e-1).setText(item.text(0))
                    j-=1
            i+=1

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Avez-vous vérifié si l'objet QListView n'était pas plus approprié pour ce que vous voulez faire ?

    http://pyqt.sourceforge.net/Docs/PyQt4/qlistview.html

    @+.

  3. #3
    Expert éminent

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 298
    Points : 6 778
    Points
    6 778
    Par défaut
    Salut,

    Normalement tu ne dois rien faire de tout cela, tu peux gérer le niveau ou se positionnera l'item
    dans les méthodes dragEnterEvent(), dragMoveEvent() et dropEvent() du treeView destinataire.

    Je ne sais pas comment est implémenté ton QTreeView, je ne pourrai pas en dire plus.

  4. #4
    Membre à l'essai
    Homme Profil pro
    Membre associatif
    Inscrit en
    Juillet 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Membre associatif

    Informations forums :
    Inscription : Juillet 2014
    Messages : 21
    Points : 15
    Points
    15
    Par défaut
    Déjà, MERCI pour votre réponse rapide.

    Pour le QlistView, peut-être, mais comme je ne sais pas trop à quoi ça ressemble (je crée les choses dans QtDesigner... je débute juste le côté interface...), et donc pas trop comment ça se code. PArtir de zéro me fait encore un peu peur... d'où l'autre solution...

    Pour le côté dragEvent(), effectivement, je ne connaissais pas.

    Je vais aller voir à quoi ça ressemble ce sera sans doute plus simple.

    Pour faire simple, un code avec la fonction implémentée à la fin de l'interface. C'est pas jolis, mais ça permet de faire un essais rapidement ^^

    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
     
    # -*- coding: utf-8 -*-
     
    #
    # Created: Wed Jul 16 15:53:57 2014
    #      by: PyQt4 UI code generator 4.10.3
    #
    # WARNING! All changes made in this file will be lost!
     
    from PyQt4 import QtCore, QtGui
     
    try:
        _fromUtf8 = QtCore.QString.fromUtf8
    except AttributeError:
        def _fromUtf8(s):
            return s
     
    try:
        _encoding = QtGui.QApplication.UnicodeUTF8
        def _translate(context, text, disambig):
            return QtGui.QApplication.translate(context, text, disambig, _encoding)
    except AttributeError:
        def _translate(context, text, disambig):
            return QtGui.QApplication.translate(context, text, disambig)
     
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName(_fromUtf8("MainWindow"))
            MainWindow.resize(478, 458)
            self.centralwidget = QtGui.QWidget(MainWindow)
            self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
            self.gridLayout = QtGui.QGridLayout(self.centralwidget)
            self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
            self.pushButton = QtGui.QPushButton(self.centralwidget)
            self.pushButton.setObjectName(_fromUtf8("pushButton"))
            self.gridLayout.addWidget(self.pushButton, 1, 0, 1, 2)
            self.treeWidget_2 = QtGui.QTreeWidget(self.centralwidget)
            self.treeWidget_2.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
            self.treeWidget_2.setDefaultDropAction(QtCore.Qt.MoveAction)
            self.treeWidget_2.setAlternatingRowColors(True)
            self.treeWidget_2.setObjectName(_fromUtf8("treeWidget_2"))
            item_0 = QtGui.QTreeWidgetItem(self.treeWidget_2)
            item_0 = QtGui.QTreeWidgetItem(self.treeWidget_2)
            item_0 = QtGui.QTreeWidgetItem(self.treeWidget_2)
            item_1 = QtGui.QTreeWidgetItem(item_0)
            self.gridLayout.addWidget(self.treeWidget_2, 0, 0, 1, 1)
            self.treeWidget_3 = QtGui.QTreeWidget(self.centralwidget)
            self.treeWidget_3.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
            self.treeWidget_3.setDefaultDropAction(QtCore.Qt.MoveAction)
            self.treeWidget_3.setAlternatingRowColors(True)
            self.treeWidget_3.setObjectName(_fromUtf8("treeWidget_3"))
            item_0 = QtGui.QTreeWidgetItem(self.treeWidget_3)
            item_0 = QtGui.QTreeWidgetItem(self.treeWidget_3)
            item_0 = QtGui.QTreeWidgetItem(self.treeWidget_3)
            item_1 = QtGui.QTreeWidgetItem(item_0)
            self.gridLayout.addWidget(self.treeWidget_3, 0, 1, 1, 1)
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtGui.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 478, 21))
            self.menubar.setObjectName(_fromUtf8("menubar"))
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtGui.QStatusBar(MainWindow)
            self.statusbar.setObjectName(_fromUtf8("statusbar"))
            MainWindow.setStatusBar(self.statusbar)
     
            self.retranslateUi(MainWindow)
            QtCore.QObject.connect(self.treeWidget_3, QtCore.SIGNAL(_fromUtf8("itemChanged(QTreeWidgetItem*,int)")), self.move2top)
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
     
        def retranslateUi(self, MainWindow):
            MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
            self.pushButton.setText(_translate("MainWindow", "PushButton", None))
            self.treeWidget_2.headerItem().setText(0, _translate("MainWindow", "1", None))
            __sortingEnabled = self.treeWidget_2.isSortingEnabled()
            self.treeWidget_2.setSortingEnabled(False)
            self.treeWidget_2.topLevelItem(0).setText(0, _translate("MainWindow", "Nouvel élément", None))
            self.treeWidget_2.topLevelItem(1).setText(0, _translate("MainWindow", "Nouvel élément", None))
            self.treeWidget_2.topLevelItem(2).setText(0, _translate("MainWindow", "Nouvel élément", None))
            self.treeWidget_2.topLevelItem(2).child(0).setText(0, _translate("MainWindow", "Nouveau sous-élément", None))
            self.treeWidget_2.setSortingEnabled(__sortingEnabled)
            self.treeWidget_3.headerItem().setText(0, _translate("MainWindow", "1", None))
            __sortingEnabled = self.treeWidget_3.isSortingEnabled()
            self.treeWidget_3.setSortingEnabled(False)
            self.treeWidget_3.topLevelItem(0).setText(0, _translate("MainWindow", "Nouvel élément", None))
            self.treeWidget_3.topLevelItem(1).setText(0, _translate("MainWindow", "Nouvel élément", None))
            self.treeWidget_3.topLevelItem(2).setText(0, _translate("MainWindow", "Nouvel élément", None))
            self.treeWidget_3.topLevelItem(2).child(0).setText(0, _translate("MainWindow", "Nouveau sous-élément", None))
            self.treeWidget_3.setSortingEnabled(__sortingEnabled)
     
        def move2top(self):
           XXX
     
     
     
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        MainWindow = QtGui.QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(MainWindow)
        MainWindow.show()
        sys.exit(app.exec_())

  5. #5
    Membre à l'essai
    Homme Profil pro
    Membre associatif
    Inscrit en
    Juillet 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Membre associatif

    Informations forums :
    Inscription : Juillet 2014
    Messages : 21
    Points : 15
    Points
    15
    Par défaut
    Je me suis permis de mettre le code entier (même si assez court) dans le précédent mail, car je comprends souvent mieux avec un exemple... c'est d'ailleurs ce que je cherchais à faire.

    En regardant les event, il semblerait d'après la doc que ce soit des fonctions "vérouillées". Du coup, comment les utiliser ? Je m'explique:

    Mon souhait est de dire : "déplace mes lignes sélectionnées de la QTreeWidget A vers B et de toujours mettre les objets dropé au rang 0 d'indentation" mais si dans le moveEvent je ne peux rien spécifier, comment faire ?

    (ps : je regarde aussi Qlistview en parallèle, mais QTreewidget me semble bien non ?).

    Je suis vraiment désolé de vous embêter avec ça mais j'ai cherché toute la journée et je deviens fous. :-( il y a des jours comme ça

  6. #6
    Membre à l'essai
    Homme Profil pro
    Membre associatif
    Inscrit en
    Juillet 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Membre associatif

    Informations forums :
    Inscription : Juillet 2014
    Messages : 21
    Points : 15
    Points
    15
    Par défaut
    Bon, comme je n'arrive pas vraiement bien à gérer les Events, je suis reparti sur ma fonction première.

    Je l'ai un peu adapté poru qu'elle fasse ce que je veux, et ça semble marcher... MAIS elle se déclenche à chaque fois que le TreeWidget change :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    QtCore.QObject.connect(self.treeWidget_3, QtCore.SIGNAL(_fromUtf8("itemChanged(QTreeWidgetItem*,int)")), self.move2top)
    Et moi ma fonction fait changer le TreeWidget... donc move2top se lance en parallèle avant que le premier ait réussi à finir sa fonction... => ça fait le job infiniement. J'ai essayé de réécrire ma prise de signal de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    QtCore.QObject.connect(self.treeWidget_3, QtCore.SIGNAL(_fromUtf8("dropEvent(QTreeWidgetItem*,int)")), self.move2top)
    Mais dropEvent ne semble pas exister... une petite aide ?

    Pour info ma fonction de traitement :

    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
     
    def move2top(self):
            print 'toto'
            nbParents = self.treeWidget_3.topLevelItemCount()  # Détecte le nombre de ligne de rang 0
     
            nbParents2 = nbParents
            i=0
     
            while i < nbParents:  # pour chaque parent on regarde si il y a des enfants
                parent_i = self.treeWidget_3.topLevelItem(i)
                nbEnfants = parent_i.childCount()
                j = nbEnfants
                if nbEnfants > 0:  # Si  nbEnfants > 0 il faut les ramener au rang du dessus
                    while j > 0:
                        newtext = parent_i.child(nbEnfants-1-j).text(0) # prends le texte du dernier enfant
                        item_0 = QtGui.QTreeWidgetItem(self.treeWidget_3)  # crée un item
                        item_0.removeChild(self.treeWidget_3.topLevelItem(i).child(nbEnfants-1-j))
                        print self.treeWidget_3.topLevelItemCount()
                        nbParents2 += 1
                        print nbParents2-1
                        '''
                        self.treeWidget_3.topLevelItem(nbParents2-1).setText(0,_translate("MainWindow",newtext,None))
                        '''
                        j-=1
                i+=1

  7. #7
    Expert éminent

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 298
    Points : 6 778
    Points
    6 778
    Par défaut
    Non, il faut sous-classer pour utiliser les méthodes dropEvent et autres.

    Ce qui n'a rien de compliqué, regarde cet exemple fonctionnel qui implemente un dragAnDrop entre un QTreeView et un QListWidget (la liste te simplifiera la vie si tu ne veux qu'un niveau d'indentation).

    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
     
    # -*- coding: utf-8 -*-
     
    import sys
    import os
     
    from PyQt4 import QtCore, QtGui
     
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.resize(569, 567)
            self.centralwidget = QtGui.QWidget(MainWindow)
            self.gridLayout = QtGui.QGridLayout(self.centralwidget)
            self.splitter = QtGui.QSplitter(self.centralwidget)
            self.splitter.setOrientation(QtCore.Qt.Horizontal)
            self.source_tree = TreeView(self, self.splitter)
            self.target_lst = ListWidget(self, self.splitter)
            self.gridLayout.addWidget(self.splitter, 0, 0, 1, 1)
            MainWindow.setCentralWidget(self.centralwidget)
            self.source_tree.set_source_model()
            self.moved_files = None
     
     
    class TreeView(QtGui.QTreeView):
        def __init__(self, main, parent=None):
            super(TreeView, self).__init__(parent)
            self.main = main
            self.setSelectionMode(QtGui.QAbstractItemView.MultiSelection)
            self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
            self.setDefaultDropAction(QtCore.Qt.CopyAction)
            self.setHeaderHidden(True)
     
        def set_source_model(self):
            self.root = QtCore.QDir.homePath()
            self.dirModel = QtGui.QFileSystemModel()
            self.dirModel.setRootPath(self.root)
            self.setModel(self.dirModel)
            self.setRootIndex(self.dirModel.index(self.root)) 
            self.setWordWrap(True)
            self.hideColumn(1)
            self.hideColumn(2)
            self.hideColumn(3)
            idx = self.dirModel.index(self.root)
            self.expand(idx)
     
        def startDrag(self, event):
            if not self.selectedIndexes():
                return
     
            paths = []
            for s in self.selectedIndexes():
                paths.append(unicode(self.dirModel.filePath(s)))
     
            self.main.moved_files = paths
            mimeData = QtCore.QMimeData()
            mimeData.setText("files")
            drag = QtGui.QDrag(self)
            drag.setMimeData(mimeData)
            result = drag.start(QtCore.Qt.MoveAction)
            event.accept()
     
        def mouseMoveEvent(self, event):
            self.startDrag(event)
     
        def mousePressEvent(self, event):
            mod = QtGui.QApplication.keyboardModifiers()
            idx = self.indexAt(event.pos())
            btn = event.button()
            if btn == 1 and (not idx.isValid() or mod == QtCore.Qt.NoModifier):
                self.clearSelection()
            QtGui.QTreeView.mousePressEvent(self, event)
     
        def dragEnterEvent(self, event):
            if event.mimeData().hasText():
                event.accept()
     
            else:
                event.ignore()
     
        def dragMoveEvent(self, event):
            if event.mimeData().hasText() and event.mimeData().text() == 'files':
                event.setDropAction(QtCore.Qt.MoveAction)
                event.accept()
     
            else:
                event.ignore()
     
        def dragLeaveEvent(self, event):
            pass
     
        def add_entries(self):
            for f in self.main.moved_files:
                name = os.path.basename(f)
                item = QtGui.QTreeWidgetItem(self)
                item.setText(0, name)
     
    class ListWidget(QtGui.QListWidget):
        def __init__(self, main, parent = None):
            super(ListWidget, self).__init__(parent)
            self.main = main
            self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
            self.setDefaultDropAction(QtCore.Qt.CopyAction)
     
        def dragEnterEvent(self, event):
            if event.mimeData().hasText():
                event.accept()
     
            else:
                event.ignore()
     
        def dragMoveEvent(self, event):
            if event.mimeData().hasText() and event.mimeData().text() == 'files':
                event.setDropAction(QtCore.Qt.MoveAction)
                event.accept()
     
            else:
                event.ignore()
     
        def dropEvent(self, event):
            if event.mimeData().hasText() and event.mimeData().text() == 'files':
                if self.main.moved_files is not None:
                    self.add_entries()
     
        def add_entries(self):
            for f in self.main.moved_files:
                name = os.path.basename(f)
                item = QtGui.QListWidgetItem()
                item.setText(name)
                self.addItem(item)
     
            self.main.moved_files = None
     
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        MainWindow = QtGui.QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(MainWindow)
        MainWindow.show()
        sys.exit(app.exec_())
    Tu peux déplacer plusieurs items en même temps.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Membre associatif
    Inscrit en
    Juillet 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Membre associatif

    Informations forums :
    Inscription : Juillet 2014
    Messages : 21
    Points : 15
    Points
    15
    Par défaut
    Ok, je comprends mieux, je croyais que ça ce gérait comme un event (d'où la création de ma fonction).
    Ma fonction semble fonctionner (sauf pour des drops interne, j'ai pas encore trouvé le truc mais ça va pas tarder). l'astuce pour régler le pb de signaux qui se répétaient sans fin est... de stoper les signaux pdt que ma fonction s'exécute (cf fonction):

    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
     
    def move2top(self):
            a=time.time()
            self.treeWidget_3.blockSignals(1)
            nbParents = self.treeWidget_3.topLevelItemCount()  # Détecte le nombre de ligne de rang 0
            nbEnfants=0
            i=0
            newtext=[]
            while i < nbParents:  # pour chaque parent on regarde si il y a des enfants
                parent_i = self.treeWidget_3.topLevelItem(i)
                nbEnfants += parent_i.childCount()
                nbEnfants_i = parent_i.childCount()
                j = nbEnfants_i-1
                if nbEnfants_i > 0:  # Si  nbEnfants > 0 il faut les ramener au rang du dessus
                    while j >= 0:
                        newtext.append(unicode(parent_i.child(j).text(0))) # prends le texte du dernier enfant
                        item_0 = QtGui.QTreeWidgetItem(self.treeWidget_3)  # crée un item
                        item_0.removeChild(self.treeWidget_3.topLevelItem(i).child(j))
                        j-=1
                i+=1
            b=time.time()
            print 'phase 1 ok. elle a dure ' + str(b-a) + ' s'
     
            a=time.time()
            if nbEnfants > 0:
                k = 0
                while k < nbEnfants:
                    parent_k = self.treeWidget_3.topLevelItem(k + nbParents)
                    parent_k.setText(0, _translate("MainWindow", newtext[k], None))
                    k+=1
            b=time.time()
            print 'phase 2 ok. elle a dure ' + str(b-a) + ' s'
            self.treeWidget_3.blockSignals(0)
    Je vais regarder ton exemple. Merci !!

  9. #9
    Membre à l'essai
    Homme Profil pro
    Membre associatif
    Inscrit en
    Juillet 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Membre associatif

    Informations forums :
    Inscription : Juillet 2014
    Messages : 21
    Points : 15
    Points
    15
    Par défaut
    Hummm, intéressant comme méthode, mais je n'arrive aps à la faire passer. Du coup, j'ai plusieurs questions :-)

    Ce que j'aimerai, c'est que quand je détecte un signal "dropped", ma fonction s'exécute :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            QtCore.QObject.connect(self.treeWidget_3, QtCore.SIGNAL("dropped"), self.move2top)
    J'ai un peu regardé ta fonction de dropevent.
    Question 1) vue que je ne cherche des infos que sur un drop, ais-je besoin des autres fonctions ?
    2) il ne me semble pas que tu émette de signat pour la fin de ton drop. C'est possible de le faire ?
    3) dans ton drop, tu regardes quel type d'objet c'est avant de l'accepter. Je n'arrive pas à trouver l'objet lié à ma ligne de QTreeWidget. J'ai essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    def dropEvent(self, event):
            if event.mimeData().selectedIndexes():
                event.setDropAction(QtCore.Qt.MoveAction)
                event.accept()
                self.emit(QtCore.SIGNAL("dropped"))
            else:
                event.ignore()
    Mais ça ne marche pas.
    Et enfin ^^
    Question 4: Dans un QTreeWidget, quand on déplace d'un parent vers un autre parent, ça crée un enfant. C'est considéré comme un drop ça ?

    Je suis à bout, mais faut que ça marche !! alors je ne baise pas les bras

  10. #10
    Expert éminent

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 298
    Points : 6 778
    Points
    6 778
    Par défaut
    Peut-être faudrait-il mieux préciser tes attentes, si tu veux une simple liste des objets déplacés, alors utilise un QListWidget (je t'ai montré un exemple, tu l'as testé ?), si tu veux plusieurs colonnes mais sans indentation alors utilise un QTableWidget.

    Je t'avoue que je ne comprend pas ce que fait ta fonction move2top, lorsque tu crées un QTreeWidgetItem l'argument que tu lui passes est son parent.
    Donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    item = QTreeWidgetItem(myTreeWidget)
    subitem = QTreeWidgetItem(item)
    donnera:
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    item = QTreeWidgetItem(myTreeWidget)
    subitem = QTreeWidgetItem(myTreeWidget)
    donnera:
    En d'autre termes, pourquoi rechercher des enfants si il suffit de ne pas les créer ?

    Pour les signaux, Je ne vois aucun signal "dropped" dans la doc, même en remontant au QAbstractItemView, mais rien ne t'empêche de le créer.

    Ça se passe comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class Foo(QtCore.QObject):
        mySignal = QtCore.pyqtSignal(args)
        def __init__(self, parent):
            ...
     
        def baz(self):
            self.mySignal.emit(args)
    Dans la déclaration QtCore.pyqtSignal(args) args doit désigner le type d'argument si il y en a sinon tu laisses les parenthèses vides.

    Et on connecte le signal de cette façon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        self.foo.mySignal.connect(self.myFunc)
    le style QtCore.QObject.connect(........) est documenté comme déprécié depuis maintenant de nombreuses années.

    Question 4: Dans un QTreeWidget, quand on déplace d'un parent vers un autre parent, ça crée un enfant. C'est considéré comme un drop ça ?
    Ça me semble être le comportement normal de tout navigateur de fichier en arborescence. Mais tu es libre de modifier ce comportement.

    Autre chose, tu as besoin de la méthode dragMoveEvent pour faire accepter le drag, sans cela le pointeur de la souris affichera une icône "No way" signifiant que le drop n'est pas permis sur ce widget.

  11. #11
    Membre à l'essai
    Homme Profil pro
    Membre associatif
    Inscrit en
    Juillet 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Membre associatif

    Informations forums :
    Inscription : Juillet 2014
    Messages : 21
    Points : 15
    Points
    15
    Par défaut
    Bonjour, merci pour ta réponse.

    Ce que je cherche à faire : une liste à plusieurs colonnes mais un seul niveau d'indentation. Mon cas concret, c'est un gestionnaire d'inscription pour des tournois. A gauche une bibliothèque de joueurs et à droite une liste de participants.

    Je souhaite faire passer les participants de l'un à l'autre par du drag and drop. Mes participants ont plusieurs caractéristiques {Nom ; prénom ; Elo ; Grade} et on doit donc pouvoir faire du tri en fonction de chacun. => la liste ne me semble donc pas adapté.
    Il me restait donc un QtreeView ou je fixait un seul niveau d'indentation (ma fonction move2top ramène tous les enfants au niveau Top Item qd elle détecte un signal), où utiliser deux QTableWidget. Mais le QTable widget a le même problème de drop qui se perd à l'intérieur du tableau... En effet si on drag une ligne d'un tableau et qu'on le lâche dans une case déjà existante d'un autre tableau... patatra la ligne qu'on voulait droper se perd... => utilisons du QtreeWidget, ce sera finalement plus simple que la Table.

    La fonction move2top fonctionne bien. Quant-on drag and drop qqch de la liste 1 vers 2, je peux détecter un signal de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    QtCore.QObject.connect(self.treeWidget_3, QtCore.SIGNAL(_fromUtf8("itemChanged(QTreeWidgetItem*,int)")), self.move2top)
    Mais quand une mauvaise manipulation est effectuée dans la liste 2 et qu'on D&D de la liste 2 vers la liste 2, le drop se fait, un indentation se crée mais pas moyen de la détecter, je ne perçois aucun signal.

    et moi, je veux que si jamais je fais ce genre de manipulation, ma fonction s'exécute aussi. Apparement se pb de détection de drop avec les QtreeWidget a l'air d'avoir été mentionné. J’espère que ça a été résolu depuis

    Enfin voilà quoi, je galère un peu hihihi

Discussions similaires

  1. Menu à 3 niveaux : 3e niveau sur plusieurs colonnes si liste longue
    Par laurentSc dans le forum Mise en page CSS
    Réponses: 13
    Dernier message: 04/07/2014, 08h54
  2. Réponses: 5
    Dernier message: 27/04/2007, 19h11
  3. liste deroulante avec plusieurs colonnes?
    Par zorba49 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 8
    Dernier message: 16/06/2006, 13h08
  4. Réponses: 4
    Dernier message: 23/09/2005, 14h29
  5. [MFC] Classer une liste a plusieur colonne
    Par Kevgeii dans le forum MFC
    Réponses: 8
    Dernier message: 07/03/2005, 16h09

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