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 :

[Résolu] [PyQt5] Comment Récupérer les lignes réorganisées d'un QTableView


Sujet :

PyQt Python

  1. #1
    Membre du Club Avatar de ptissendier
    Homme Profil pro
    Retraité
    Inscrit en
    Juillet 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juillet 2011
    Messages : 64
    Points : 53
    Points
    53
    Par défaut [Résolu] [PyQt5] Comment Récupérer les lignes réorganisées d'un QTableView
    Bonjour,
    Je me relance dans PyQt5.
    Pour Charger et Réorganiser mon QTableview j'ai trouvé ça http://apocalyptech.com/linux/qt/qtableview/ que j'ai adapté aux données que je veux Charger.
    La où je butte c'est après la réorganisation (ce n'est pas un tri croisant/décroissant), comment faire pour récupérer le modèle dans le nouvel ordre (le catalogue) en cliquant sur le bouton "enregistrer"
    Voici le code
    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
    #!/usr/bin/env python
    # vim: set expandtab tabstop=4 shiftwidth=4:
     
    #   Qt5 - Drag-and-Drop Reordering of Rows in a QTableView
    #    http://apocalyptech.com/linux/qt/qtableview/
     
    # =======================================
     
    import sys
    from PyQt5 import QtWidgets, QtGui, QtCore
     
    class MyModel(QtGui.QStandardItemModel):
     
        def dropMimeData(self, data, action, row, col, parent):
            """
            Always move the entire row, and don't allow column "shifting"
            """
            return super().dropMimeData(data, action, row, 0, parent)
     
    class MyStyle(QtWidgets.QProxyStyle):
     
        def drawPrimitive(self, element, option, painter, widget=None):
            """
            Draw a line across the entire row rather than just the column
            we're hovering over.  This may not always work depending on global
            style - for instance I think it won't work on OSX.
            """
            if element == self.PE_IndicatorItemViewItemDrop and not option.rect.isNull():
                option_new = QtWidgets.QStyleOption(option)
                option_new.rect.setLeft(0)
                if widget:
                    option_new.rect.setRight(widget.width())
                option = option_new
            super().drawPrimitive(element, option, painter, widget)
     
    class MyTableView(QtWidgets.QTableView):
     
        def __init__(self, parent):
            super().__init__(parent)
            self.verticalHeader().hide()
            self.horizontalHeader().hide()
            self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
            self.setSelectionBehavior(self.SelectRows)
            self.setSelectionMode(self.SingleSelection)
            self.setShowGrid(False)
            self.setDragDropMode(self.InternalMove)
            self.setDragDropOverwriteMode(False)
     
            # Set our custom style - this draws the drop indicator across the whole row
            self.setStyle(MyStyle())
     
            # Set our custom model - this prevents row "shifting"
            self.model = MyModel()
            self.setModel(self.model)
     
            catalogue=QtWidgets.QFileDialog.getOpenFileNames(self,"Sélection de fichier(s)","/home/","*")
     
     
            # for (idx, data) in enumerate(['foo', 'bar', 'baz']):
                # item_1 = QtGui.QStandardItem('Item {}'.format(idx))
                # item_1.setEditable(False)
                # item_1.setDropEnabled(False)
     
                # item_2 = QtGui.QStandardItem(data)
                # item_2.setEditable(False)
                # item_2.setDropEnabled(False)
     
     
            for F in catalogue[0]:
               i=catalogue[0].index(F)
               title=F.split("/")[-1][0:-4] 
               # item_1 = QtGui.QStandardItem('{}'.format(i))
               # item_1.setEditable(False)
               # item_1.setDropEnabled(False)
     
               item_2 = QtGui.QStandardItem(title)
               item_2.setEditable(False)
               item_2.setDropEnabled(False)           
     
               self.model.appendRow([item_2])
     
     
     
            for i in range(0, self.model.rowCount()):
               print(self.model.item(i).data(QtCore.Qt.DisplayRole))
     
               # data2 = [str(ch) for ch in list(self.model().stringList())]
               # print(data2)
     
    class Testing(QtWidgets.QMainWindow):
     
        def __init__(self):
            super().__init__()
     
            # Main widget
            w = QtWidgets.QWidget()
            l = QtWidgets.QVBoxLayout()
            w.setLayout(l)
            self.setCentralWidget(w)
     
     
            # ajout d'un bouton pour valider la reorganisation
            saveCatalogButton=QtWidgets.QPushButton("Enregistre le catalogue")
            saveCatalogButton.clicked.connect(self.saveCatalog)
     
            # spacer
            # l.addWidget(QtWidgets.QLabel('top'), 1)
     
            # Combo Box
            l.addWidget(MyTableView(self))
     
            # spacer
            l.addWidget(saveCatalogButton)
     
            # A bit of window housekeeping
            self.resize(600, 400)
            self.setWindowTitle('Testing')
     
     
            # Sauvegarde du catalogue vers .... une sortie fichier ou autre  
        def saveCatalog(self):
     
           print("bonjour - le bouton est clqué")
     
           print( "le nouveau catalogue")
     
     
     
     
     
     
     
     
    if __name__ == '__main__':
     
        app = QtWidgets.QApplication([])
        test = Testing()
        test.show()
        sys.exit(app.exec_())
    J'ai un peu de mal à comprendre comment fonctionne le Qtableview et son modèle
    Il y a peut-être plus simple avec une Qlistview (mais il faut pouvoir la réorganiser)
    Merci de votre aide
    Ubuntu 22.04.1 LTS
    LibreOffice 7.4.3

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    C'est en effet déconcertant au début: on ne peut pas lire les cases du QTableView comme on le ferait avec un QTableWidget, puisqu'il faut passer par le modèle.

    Voilà un petit code d'essai que j'avais fait pour récupérer les données affichées en faisant Alt-X au clavier:

    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 keyPressEvent(self, event):
            if self.tablevue.hasFocus():
                if event.key() == QtCore.Qt.Key_X and (event.modifiers() & QtCore.Qt.AltModifier):
                    # récupére la liste data après modification
                    imax, jmax = self.tablevue.model().rowCount(), self.tablevue.model().columnCount()
                    data2 = []
                    for i in range(0, imax):
                        data2.append([]) # nouvelle ligne
                        for j in range(0, jmax):
                            item = self.tablevue.model().item(i,j)
                            elem = item.data(QtCore.Qt.DisplayRole)
                            data2[-1].append(elem)
                    print(data2)
                    event.accept()
                else:
                    event.ignore()
            else:
                event.ignore()
    Il s'agit bien des données affichées, y compris en prenant en compte les éventuels tris.

    Le "print(data2)" affiche en console la valeur du tableau affiché.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  3. #3
    Membre du Club Avatar de ptissendier
    Homme Profil pro
    Retraité
    Inscrit en
    Juillet 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juillet 2011
    Messages : 64
    Points : 53
    Points
    53
    Par défaut
    Merci Tyrtamos,
    Je n'arrive pas à comprendre dans qu'elle classe je doit tester le keypress. MyTableView ou Testing ?

    Autre chose mais qui n'est pas bloquant : je reçois l'erreur suivante en console
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Gtk-Message: 11:08:25.551: GtkDialog mapped without a transient parent. This is discouraged.
    Comment s'en débarrasser?

    Meric encore pour ton attention surtout un samedi soir.
    Ubuntu 22.04.1 LTS
    LibreOffice 7.4.3

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Dans ma réponse, ce n'est pas le keyPressEvent qui est important, mais ce que je fais pour obtenir les valeurs affichées. Tu peux ainsi créer une méthode, qu'il faut mettre dans la classe où tu as accès à la variable du QTableView:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        def littableau(self):
            imax, jmax = self.tablevue.model().rowCount(), self.tablevue.model().columnCount()
            data2 = []
            for i in range(0, imax):
                data2.append([]) # nouvelle ligne
                for j in range(0, jmax):
                    item = self.tablevue.model().item(i,j)
                    elem = item.data(QtCore.Qt.DisplayRole)
                    data2[-1].append(elem)
            return data2
    Dans le code que tu donnes, c'est dans ta fenêtre QMainWindows que tu mets le QTableView, c'est donc dans cette fenêtre que tu pourras le lire. Mais il faut appeler le QTableView et lui donner un nom avant de le positionner dans la fenêtre avec le QVBoxLayout. Cela donnerait quelque chose comme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            # crée le QTableView
            self.tablevue = MyTableView(self)
     
            # Place le QTableView dans la fenêtre:
            l.addWidget(self.tablevue)#MyTableView(self))
    Je ne suis pas allé plus loin dans la lecture de ton code, mais il y a des problèmes d'indentation dans les lignes qui suivent "for F in catalogue[0]:"

    Quant à l'erreur que tu cites, je ne sais pas: Gtk est une autre bibliothèque graphique: celle de Linux Gnome.

    A part ça, une bibliothèque graphique comme PyQt5 est en même temps puissante et complexe: on doit avoir la doc en ligne en permanence, sinon, on n'avance pas:
    https://www.riverbankcomputing.com/static/Docs/PyQt5/
    https://doc.qt.io/qt-5/index.html
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  5. #5
    Membre du Club Avatar de ptissendier
    Homme Profil pro
    Retraité
    Inscrit en
    Juillet 2011
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juillet 2011
    Messages : 64
    Points : 53
    Points
    53
    Par défaut
    Super !!! Ça marche !!!
    Je te remercie infiniment



    Je suis bien d'accord avec toi sur la richesse et la complexité de PyQt
    Je vais suivre tes conseils.
    Je passe le sujet à résolu et encore
    Ubuntu 22.04.1 LTS
    LibreOffice 7.4.3

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 27/07/2010, 13h59
  2. Réponses: 5
    Dernier message: 08/03/2010, 15h09
  3. Comment récupérer les lignes en erreur
    Par StéphanieB. dans le forum Informatica
    Réponses: 1
    Dernier message: 23/12/2009, 17h39
  4. Réponses: 5
    Dernier message: 20/07/2007, 16h15
  5. Réponses: 2
    Dernier message: 11/12/2006, 13h38

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