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 :

Rendre copiable un QTableWidget [QtGui]


Sujet :

PyQt Python

  1. #1
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2014
    Messages
    98
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2014
    Messages : 98
    Points : 59
    Points
    59
    Par défaut Rendre copiable un QTableWidget
    Bonjour,

    J'ai une question relativement simple mais dont je n'ai pas la solution.
    J'ai dans une ui un QtableWidget définit comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    self.tableWidget = QtGui.QTableWidget(self.gpBox_details)
    self.tableWidget.setGeometry(QtCore.QRect(10, 20, 301, 191))
    self.tableWidget.setDragEnabled(False)
    self.tableWidget.setSelectionMode(QtGui.QAbstractItemView.MultiSelection)
    self.tableWidget.setTextElideMode(QtCore.Qt.ElideNone)
    self.tableWidget.setObjectName(_fromUtf8("tableWidget"))
    self.tableWidget.setColumnCount(0)
    self.tableWidget.setRowCount(0)
    Ce que j'aimerais c'est pouvoir selectionner soit toutes les cellules, soit une ou plusieurs colonne et/ou ligne et copier leur contenue dans un fichier excel par exemple.
    Pour le moment seul le contenue d'une unique cellule est copié.

    Merci d'avance
    Aurélie

  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 Aurélie,

    C'est intéressant comme question. D'abord comment copies-tu ?

    Est-ce que tu utilises CTRL+C, ou un item de menu, ou un bouton dans l'interface ?

    Dans le cas du CTRL+C, il y a de fortes chances que ton presse-papier soit chargé de la "Global selection" [0] et, là, c'est le système qui gère, tu n'as pas de possibilité d'intervention.

    Par contre, si tu utilises un item de menu Copier, donc avec le raccourcis CTRL+C, avec la méthode QTableWidget.selectedItems() qui retourne une liste de QTableWidgetItem, ceux-ci ayant des méthodes column() et row(), tu peux reconstituer la partie de tableau que constitue la sélection et l'enregistrer en csv.


    [0] "Global selection" (comme "Global clipboard") est un terme Linux et désigne toute chose sélectionnée dans nimporte quel espace, application graphique, bureau, et transposable dans nimporte quel autre espace. Les utilisateurs Windows adapterons le terme à celui de leur OS.

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

    Voilà un petit code qui montre comment on peut faire pour échanger des zones sélectionnées par copier-coller entre un QTableWidget (pas un QTableView!) et Excel (Python 3, PyQt4):

    Ça ne marche pour l'instant que pour des sélections contiguës.

    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
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    # Python 3
     
    import sys
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        # =======================================================================
        def __init__(self, parent=None):
            super(Fenetre, self).__init__(parent)
     
            self.resize(800, 600)
     
            self.tableWidget = QtGui.QTableWidget(self)
            self.nbrow, self.nbcol = 7, 7
            self.tableWidget.setRowCount(self.nbrow)
            self.tableWidget.setColumnCount(self.nbcol)
     
            self.tableWidget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
     
            posit = QtGui.QGridLayout()
            posit.addWidget(self.tableWidget, 0, 0)
            self.setLayout(posit)
     
            self.tableWidget.setFocus()
            self.tableWidget.setCurrentCell(0, 0)
     
        # =======================================================================
        def copier(self):
            """copier la zone sélectionnée dans le clipboard
            """
            # emplacement sélectionné pour copier dans le clipboard
            selected = self.tableWidget.selectedRanges()
     
            # construction du texte à copier, ligne par ligne et colonne par colonne
            texte = ""
            for i in range(selected[0].topRow(), selected[0].bottomRow() + 1):
                for j in range(selected[0].leftColumn(), selected[0].rightColumn() + 1):
                    try:
                        texte += self.tableWidget.item(i, j).text() + "\t"
                    except AttributeError:
                        # quand une case n'a jamais été initialisée
                        texte += "\t"
                texte = texte[:-1] + "\n"  # le [:-1] élimine le '\t' en trop
     
            # enregistrement dans le clipboard
            QtGui.QApplication.clipboard().setText(texte)
     
        # =======================================================================
        def coller(self):
            """coller le contenu du clipboard dans la zone sélectionnée
            """
     
            # zone sélectionnée pour coller le contenu du clipboard
            selected = self.tableWidget.selectedRanges()
     
            # coordonnées de la case en haut à gauche de la zone sélectionnée
            row0 = selected[0].topRow()
            col0 = selected[0].leftColumn()
     
            # récup du contenu du clipboard
            texte = QtGui.QApplication.clipboard().text()
     
            # placer ce contenu dans le QTableWidget
            for i, texteligne in enumerate(texte.split('\n')):
                for j, textecase in enumerate(texteligne.split('\t')):
                    self.tableWidget.setItem(row0 + i, col0 + j, QtGui.QTableWidgetItem(textecase))
     
        # =======================================================================
        def keyPressEvent(self, event):
     
            if self.tableWidget.hasFocus():
     
                #----------------------------------------------------------------
                # Ctle-C: copier
                if event.key() == QtCore.Qt.Key_C and  (event.modifiers() & QtCore.Qt.ControlModifier):
                    self.copier()
                    event.accept()
     
                #----------------------------------------------------------------
                # Ctle-V: coller
                if event.key() == QtCore.Qt.Key_V and  (event.modifiers() & QtCore.Qt.ControlModifier):
                    self.coller()
                    event.accept()
     
                #----------------------------------------------------------------
                else:
                    event.ignore()
            else:
                event.ignore()
     
    #############################################################################
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())
    [Edit] comme ça ne marche que pour des sélections contiguës, il est plus logique de sélectionner le mode contigu:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.tableWidget.setSelectionMode(QtGui.QAbstractItemView.ContiguousSelection)
    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

  4. #4
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2014
    Messages
    98
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2014
    Messages : 98
    Points : 59
    Points
    59
    Par défaut
    Bonjour à tous,

    Je répond un peu tard mais j'ai pas eu le temps de me remettre sur mon code depuis une bonne grosse semaine !

    VinsS :
    Est-ce que tu utilises CTRL+C, ou un item de menu, ou un bouton dans l'interface ?
    Oui en effet c'était pour faire un CTRL+C simplement. Pour que mon ulitisateur puisse récupérer les données si il a bessoin.

    tyrtamos :
    Merci pour ce petit code et ses explications ! Tous marche comme je le souhaite !

    Merci à pour vos réponses vous m'avez encore une fois évité de longues heures à me perdre dans les documentations et sur les forums.

    Bonne semaine !
    Aurélie

  5. #5
    Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2015
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Novembre 2015
    Messages : 1
    Points : 2
    Points
    2
    Par défaut Une petite erreur
    Citation Envoyé par tyrtamos Voir le message
    Bonjour,

    Voilà un petit code qui montre comment on peut faire pour échanger des zones sélectionnées par copier-coller entre un QTableWidget (pas un QTableView!) et Excel (Python 3, PyQt4):

    Ça ne marche pour l'instant que pour des sélections contiguës.

    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
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    # Python 3
     
    import sys
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        # =======================================================================
        def __init__(self, parent=None):
            super(Fenetre, self).__init__(parent)
     
            self.resize(800, 600)
     
            self.tableWidget = QtGui.QTableWidget(self)
            self.nbrow, self.nbcol = 7, 7
            self.tableWidget.setRowCount(self.nbrow)
            self.tableWidget.setColumnCount(self.nbcol)
     
            self.tableWidget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
     
            posit = QtGui.QGridLayout()
            posit.addWidget(self.tableWidget, 0, 0)
            self.setLayout(posit)
     
            self.tableWidget.setFocus()
            self.tableWidget.setCurrentCell(0, 0)
     
        # =======================================================================
        def copier(self):
            """copier la zone sélectionnée dans le clipboard
            """
            # emplacement sélectionné pour copier dans le clipboard
            selected = self.tableWidget.selectedRanges()
     
            # construction du texte à copier, ligne par ligne et colonne par colonne
            texte = ""
            for i in range(selected[0].topRow(), selected[0].bottomRow() + 1):
                for j in range(selected[0].leftColumn(), selected[0].rightColumn() + 1):
                    try:
                        texte += self.tableWidget.item(i, j).text() + "\t"
                    except AttributeError:
                        # quand une case n'a jamais été initialisée
                        texte += "\t"
                texte = texte[:-1] + "\n"  # le [:-1] élimine le '\t' en trop
     
            # enregistrement dans le clipboard
            QtGui.QApplication.clipboard().setText(texte)
     
        # =======================================================================
        def coller(self):
            """coller le contenu du clipboard dans la zone sélectionnée
            """
     
            # zone sélectionnée pour coller le contenu du clipboard
            selected = self.tableWidget.selectedRanges()
     
            # coordonnées de la case en haut à gauche de la zone sélectionnée
            row0 = selected[0].topRow()
            col0 = selected[0].leftColumn()
     
            # récup du contenu du clipboard
            texte = QtGui.QApplication.clipboard().text()
     
            # placer ce contenu dans le QTableWidget
            for i, texteligne in enumerate(texte.split('\n')):
                for j, textecase in enumerate(texteligne.split('\t')):
                    self.tableWidget.setItem(row0 + i, col0 + j, QtGui.QTableWidgetItem(textecase))
     
        # =======================================================================
        def keyPressEvent(self, event):
     
            if self.tableWidget.hasFocus():
     
                #----------------------------------------------------------------
                # Ctle-C: copier
                if event.key() == QtCore.Qt.Key_C and  (event.modifiers() & QtCore.Qt.ControlModifier):
                    self.copier()
                    event.accept()
     
                #----------------------------------------------------------------
                # Ctle-V: coller
                if event.key() == QtCore.Qt.Key_V and  (event.modifiers() & QtCore.Qt.ControlModifier):
                    self.coller()
                    event.accept()
     
                #----------------------------------------------------------------
                else:
                    event.ignore()
            else:
                event.ignore()
     
    #############################################################################
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())
    [Edit] comme ça ne marche que pour des sélections contiguës, il est plus logique de sélectionner le mode contigu:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.tableWidget.setSelectionMode(QtGui.QAbstractItemView.ContiguousSelection)
    Bonjour,

    Ton code m'a été fort utile, cependant j'ai du corriger un petit bout dans la méthode "copier" car lorsque la méthode "coller" était appelée il apparaissait des cases blanches dues à la construction du tableau dans "copier"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
               if i != selected[0].bottomRow():
                    texte = texte[:-1] + "\n"  # le [:-1] élimine le '\t' en trop
                else:
                    texte = texte[:-1]
    Ces quatre ligne viennent remplacer cette ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
             texte = texte[:-1] + "\n"  # le [:-1] élimine le '\t' en trop
    Bonne continuation

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

Discussions similaires

  1. Comment rendre les contenus des pages d'un site non téléchargeables et non copiables
    Par isabelle06am dans le forum Général Conception Web
    Réponses: 4
    Dernier message: 02/07/2015, 15h19
  2. Rendre une structure non copiable
    Par dancingmad dans le forum C
    Réponses: 14
    Dernier message: 10/12/2014, 10h25
  3. [QtGui] QTableWidget : Rendre chekable les items de une colonne
    Par aurelie.guegan.15 dans le forum PyQt
    Réponses: 7
    Dernier message: 23/11/2014, 17h22

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