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 :

Affichage optimal d'une arborescence (QTreeView) ? [QtGui]


Sujet :

PyQt Python

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 35
    Points : 99
    Points
    99
    Par défaut Affichage optimal d'une arborescence (QTreeView) ?
    Bonjour,


    Je cherche à afficher une arborescence afin de permettre à l'utilisateur de choisir le dossier voulu.

    Pour le moment j'obtiens facilement l'arborescence grâce à la ligne de commande:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    subprocess.call(['tree', "-L", "2", myPath])
    Avec pour résultat:
    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
    |-- A
    |   |-- 1
    |   |-- 2
    |   |-- 3
    |   |-- 4
    |   |-- 5
    |   `-- 6
    |-- B
    |   |-- 1
    |   |-- 2
    |   |-- 3
    |   |-- 4
    |   |-- 5
    |   `-- 6
    `-- C
        |-- 1
        |-- 2
        |-- 3
        |-- 4
        |-- 5
        `-- 6
    Seulement je voudrais désormais obtenir cette arborescence dans une interface graphique.
    J'ai donc créé un QTreeView:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.myTree.setRootIndex(self.model.index(myPath))
    Mes questions:
    • Le problème étant que j'ai désormais l'affichage de tout les sous-dossiers (contrairement à l'option -L 2 du tree)
      Une solution ?
    • Est-il également possible de n'afficher que la première colonne (le nom) et de masquer les autres (taille, date) ?
    • Comment récupérer la sélection de l'utilisateur ?
    • Le QTreeView est-il vraiment la meilleure solution pour ce type d'affichage (QDirModel ?) ?



    Merci d'avance.

  2. #2
    Expert éminent

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

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


    Le treeView convient très bien pour ça.

    Le man de tree étant muet sur l'option -L je suppose que tu ne veux afficher que les fichiers, dans ce cas tu peux utiliser QDir.Filters.

    Quelque chose comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
            self.model = QtGui.QFileSystemModel()
            self.model.setFilter(QtCore.QDir.Files)
            self.model.setRootPath(QtCore.QDir.homePath())
            self.myTree.setModel(self.model)
            self.myTree.setRootIndex(self.model.index(path))
    Pas testé ...

    Pour cacher les colonnes le treeView a une méthode setColumnHidden (self, int column, bool hide) et pour saisir la sélection de fichier par l'utilisateur, tu peux utiliser selectionChanged mais ce n'est pas un signal, c'est une méthode que tu dois réimplémenter.

  3. #3
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 35
    Points : 99
    Points
    99
    Par défaut
    Merci pour ces réponses !

    Je les teste et je reviens donner les résultats.



    Citation Envoyé par VinsS Voir le message
    Le man de tree étant muet sur l'option -L je suppose que tu ne veux afficher que les fichiers, dans ce cas tu peux utiliser QDir.Filters.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
          -L level
                  Max display depth of the directory tree.

    Je ne cherche pas à afficher uniquement les fichiers mais je veux restreindre la récursivité.

    Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    subprocess.call(['tree', myPath])
     
    -- A
       |-- 1
       |   |-- a
       |   `-- b
       |-- 2
       |   |-- a
       |   `-- b
       `-- 3
           |-- a
           `-- b
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    subprocess.call(['tree', "-L", "2", myPath])
     
    -- A
       |-- 1
       |-- 2
       `-- 3

  4. #4
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 35
    Points : 99
    Points
    99
    Par défaut
    Citation Envoyé par VinsS Voir le message
    Pour cacher les colonnes le treeView a une méthode setColumnHidden (self, int column, bool hide) et pour saisir la sélection de fichier par l'utilisateur, tu peux utiliser selectionChanged mais ce n'est pas un signal, c'est une méthode que tu dois réimplémenter.
    Merci !

    Je suis en train de m'aider de ce sujet pour la gestion de l’événement.


    Il ne reste plus qu'à trouver comment limiter l'affichage des sous-dossier (comme avec l'option -L de tree) pour que tout soit parfait.
    Je n'ai encore rien trouvé d'intéressant à ce sujet

  5. #5
    Expert éminent

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Je ne vois pas non plus comment limiter la profondeur de l'arbre, du moins avec QDir.Filter

    Par contre, en réimplémentant le treeView, on peut alors faire tout ce que l'on veut.

    Entrons dans l'univers magique du sous-classement:
    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
     
    # -*- coding: utf-8 -*-
     
    import sys, os
     
    from PyQt4.QtCore import Qt, QSize, QDir
    from PyQt4.QtGui import (QMainWindow, QWidget, QGridLayout, QVBoxLayout,
                             QHBoxLayout, QTreeView, QPlainTextEdit, QSpacerItem,
                             QPushButton, QApplication, QSizePolicy, QFileSystemModel,
                             QAbstractItemView, QItemDelegate, QPen, QColor)
     
    class Main(QMainWindow):
        def __init__(self):
            super(Main, self).__init__()
            self.resize(413, 580)
            self.cw = QWidget(self)
            self.gl = QGridLayout(self.cw)
            self.vl = QVBoxLayout()
            self.treeView = TreeView(self, self.cw)
            self.vl.addWidget(self.treeView)
            self.editor_pte = QPlainTextEdit(self.cw)
            self.editor_pte.setMaximumSize(QSize(16777215, 150))
            self.vl.addWidget(self.editor_pte)
            self.hl = QHBoxLayout()
            spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
            self.hl.addItem(spacer)
            self.unselect_btn = QPushButton(self.cw)
            self.unselect_btn.setText(u"Désélectionner")
            self.hl.addWidget(self.unselect_btn)
            self.vl.addLayout(self.hl)
            self.gl.addLayout(self.vl, 0, 0, 1, 1)
            self.setCentralWidget(self.cw)
     
            self.unselect_btn.clicked.connect(self.on_deselect_clicked)
            self.treeView.set_source(u'/home/vincent/Images')
     
        def show_selection(self, selection):
            self.editor_pte.clear()
            txt = '\n'.join(selection)
            self.editor_pte.setPlainText(txt)
     
        def on_deselect_clicked(self):
            self.treeView.clearSelection()
     
    class TreeView(QTreeView):
        def __init__(self, main, parent=None):
            super(TreeView, self).__init__(parent)
            self.main = main
            self.setHeaderHidden(True)
            self.setSelectionMode(QAbstractItemView.MultiSelection)
            delegate = ItemDelegate(self)
            self.setItemDelegate(delegate)
     
        def set_source(self, folder):
            folder = folder.rstrip(os.path.sep)
            self.top = folder
            self.root = os.path.dirname(folder)
            self.dirModel = QFileSystemModel()
            # A adapter au contexte
            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(folder)
            self.expand(idx)
            self.scrollTo(idx, QAbstractItemView.EnsureVisible)
     
        def selectionChanged(self, new, old):
            sel = [unicode(self.model().filePath(idx)) for idx in self.selectedIndexes()]
            self.main.show_selection(sel)
     
     
    class ItemDelegate(QItemDelegate):
        def __init__(self, tree, parent=None):
            super(ItemDelegate, self).__init__(parent)
            self.tree = tree
            # Si l'on veut des icônes ...
            #self.file_px = QtGui.QPixmap('medias/file_ico.png')
            #self.exp_px = QtGui.QPixmap('medias/folder_open.png')
            #self.coll_px = QtGui.QPixmap('medias/folder_close.png')
     
        def createEditor(self, parent, option, index):
            return QItemDelegate.createEditor(self, parent, option, index)
     
        def paint(self, painter, option, index):
            path = unicode(self.tree.model().filePath(index))
            # C'est ici que ça se passe:
            # Si le parent du dossier-fichier n'est pas le root du treeView alors
            # c'est qu'il est dans un sous dossier, donc on l'ignore
            if not os.path.dirname(path) == self.tree.top:
                return
     
            painter.save()
            x, y = option.rect.x(), option.rect.y()
            pen = QPen()
            pen.setBrush(QColor(255, 255, 255, 255))
            painter.setPen(pen)
            painter.drawRect(option.rect)
            painter.setPen(QPen(QColor(0, 0, 0, 255)))
     
            if index in self.tree.selectedIndexes():
                background = painter.background()
                backgroundMode = painter.backgroundMode()
                painter.setBackground(self.tree.palette().highlight())
                painter.setBackgroundMode(Qt.OpaqueMode)
     
            # Si l'on veut des icônes ...
            #icon = self.get_icon(index)
            #painter.drawPixmap(x, y, icon)
     
            value = index.data(Qt.DisplayRole)
            if value.isValid():
                text = value.toString()
                painter.drawText(x + 25, y + 14, text)
     
            painter.restore()
     
        def get_icon(self, idx):
            if self.tree.dirModel.isDir(idx):
                if self.tree.isExpanded(idx):
                    return self.exp_px
     
                return self.coll_px
     
            return self.file_px
     
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        ui = Main()
        ui.show()
        sys.exit(app.exec_())

  6. #6
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 35
    Points : 99
    Points
    99
    Par défaut
    Merci,

    Je n'ai pas pu regarder ce week-end, je vais donc essayer cette semaine et je viendrai donner mes résultats (si j'en ai )

  7. #7
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 35
    Points : 99
    Points
    99
    Par défaut
    Merci !

    Votre exemple m'a permit de trouver une solution.

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

Discussions similaires

  1. Affichage d'une arborescence
    Par jbrasselet dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 02/08/2012, 15h24
  2. Affichage d'une arborescence
    Par kotakota dans le forum Servlets/JSP
    Réponses: 0
    Dernier message: 16/07/2012, 15h25
  3. Affichage d'une arborescence
    Par lina22 dans le forum Langage
    Réponses: 2
    Dernier message: 10/07/2009, 16h08
  4. Affichage d'une arborescence de dossiers
    Par Contractofoued dans le forum Interfaces Graphiques
    Réponses: 4
    Dernier message: 04/09/2007, 15h07

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