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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    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
    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 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 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 averti
    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
    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 averti
    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
    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 averti
    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
    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 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
    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.

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, 07h54
  2. Réponses: 5
    Dernier message: 27/04/2007, 18h11
  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, 12h08
  4. Réponses: 4
    Dernier message: 23/09/2005, 13h29
  5. [MFC] Classer une liste a plusieur colonne
    Par Kevgeii dans le forum MFC
    Réponses: 8
    Dernier message: 07/03/2005, 15h09

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