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 :

Séparateur des milliers dans un QTableView [QtGui]


Sujet :

PyQt Python

  1. #1
    Membre du Club

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Burkina Faso

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2014
    Messages : 39
    Points : 41
    Points
    41
    Billets dans le blog
    1
    Par défaut Séparateur des milliers dans un QTableView
    Bonjour,

    je dispose d'une liste bidimensionnelle qui alimente mon QTableView, et dans cette liste il y a des nombres et j'aimerais savoir comment faire pour introduire un separateur de milliers, disons un espace, pour des besoins de lisibilité. Merci

  2. #2
    Expert éminent

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

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

    comme ceci, par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    >>> from PyQt4 import QtCore
    >>> n = 123654789
    >>> loc = QtCore.QLocale.system().name()
    >>> lang = QtCore.QLocale(loc)
    >>> x = unicode(lang.toString(n))
    >>> x
    u'123\xa0654\xa0789'
    >>> print x
    123 654 789

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

    Que ce soit des nombres entiers ou des flottants, on peut proposer aussi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    x = 1234567890
    print "{:,}".format(x).replace(',', ' ')
    '1 234 567 890'
     
    y = 123456789.01
    print "{:,}".format(y).replace(',', ' ')
    '123 456 789.01'
    Mais ça ne suffit pas pour résoudre le problème posé. En effet, contrairement au QTableWidget, le QTableView affiche de manière standard les données transmises par son modèle. Donc, pour personnaliser l'affichage, il faut probablement modifier le modèle. Et s'il fallait en plus permettre à l'utilisateur de modifier ces nombres affichés, il faudrait aussi utiliser un delegate modifié.

    Bref, il faut en dire un peu plus sur le problème à résoudre si tu veux plus de solution. Et donne la version de ton Python.

  4. #4
    Membre du Club

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Burkina Faso

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2014
    Messages : 39
    Points : 41
    Points
    41
    Billets dans le blog
    1
    Par défaut
    Merci vinsS et tyrtamos; vos deux solutions machent et j'ai pu faire ce que je voulais.

    J'ai aussi appliqué vos deux méthodes à des QLineEdit et c'est impossible de retrouver les nombres lorsque j'utilise QLineEdit.text(). J'ai essayé en vain de convertir ce que je récupère... un hint

    @tyrtamos, au fait j'ai voulu permettre la modification des données directement dans le QTableView mais lorsque je tente il y a des erreurs que je n'arrive pas à comprendre surtout issues de la methode flags, du coup j'ai abandonné. Pouvez-vous me guider comment faire cela lorsque le modèle et le delegate gère une liste de listes genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     l = [[101,"Transfert 1000",45,26,10,456,7888]]
    Merci

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

    Voilà un code de test qui devrait faire ce que tu souhaites.

    Il est écrit en Python 2.7 / PyQt4, mais il ne devrait pas être difficile à convertir.

    Dans l'exemple, j'ai limité l'affichage particulier voulu à la colonne d'indice 6, mais on peut bien sûr faire autrement.

    Le principe est simple (le code un peu moins...): on sous-classe le delegate (un QtGui.QStyledItemDelegate) et on surcharge sa méthode paint.

    Dans sa méthode paint, on traite les cas particuliers (if index.column()==6), et on renvoie les autres à la méthode normale de l'ancêtre.

    Quand on veut modifier l'une des cases (n'importe laquelle), on double-clique et on se retrouve dans le mode d'édition.
    Dans ce mode, les entiers sont édités par des QSpinBox. Pour les entiers ayant un affichage particulier: il sont édités comme des nombres normaux, sans les espaces supplémentaires.
    En sortie d'édition, on retrouve ces même nombres affichés avec les espaces supplémentaires.

    A noter que cette façon de faire permet de faire des affichages particuliers comme par exemple d'écrire en rouge les nombres négatifs (ou simplement situés hors d'une plage définie).

    Il faut se rappeler que lorsqu'on modifie de telles données dans le QTableView, le tableau initial (la liste de listes appelée ici data) n'est pas modifié. J'ai donc ajouté à la fenêtre principale la méthode datasmodif() qui permettra de la retrouver. Et pour le test, j'ai ajouté l'affichage en console de la liste initiale et de la liste modifiée, déclenché avec un simple Alt-X.

    Voilà le code de test complet (Il est déjà documenté):

    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
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division, print_function, unicode_literals
    # Python 2.7
     
    import sys, os
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    class StyleDelegate(QtGui.QStyledItemDelegate):
        """permet de changer l'affichage des données dans chaque case"""
     
        #========================================================================
        def __init__(self, parent=None):
            super(StyleDelegate, self).__init__(parent)
     
        #========================================================================
        def paint(self, painter, option, index):
            """affichage de chaque case
               type des arguments:
                   painter: QtGui.QPainter
                   option: QtGui.QStyleOptionViewItemV4
                   index: QtCore.QModelIndex
            """
     
            # modifier l'affichage des nombres de la colonne d'indice 6
            if index.column()==6:
     
                # sauvegarde les valeurs du painter
                painter.save() 
     
                # rectangle de la case d'affichage
                rect = option.rect 
     
                # pour que la case courante qui a le focus soit en bleu 
                if option.state & QtGui.QStyle.State_Selected:                
                    # fond de la case en bleu
                    painter.fillRect(option.rect, option.palette.highlight())            
                    # texte en blanc pour le contraste avec le bleu
                    pen = painter.pen()
                    pen.setColor(QtGui.QApplication.palette().color(QtGui.QPalette.HighlightedText))
                    painter.setPen(pen)
                else:
                    # fond des cases "normales" (non courantes)
                    painter.fillRect(option.rect, QtGui.QBrush(index.data(QtCore.Qt.BackgroundRole)))                                            
     
                # récupérer le nombre entier à afficher
                nb = index.model().data(index, QtCore.Qt.DisplayRole).toInt()[0]
     
                # formater le nombre pour affichage
                value = "{:,}".format(nb).replace(',', ' ')
     
                # afficher le nombre
                painter.drawText(rect, QtCore.Qt.AlignVCenter | QtCore.Qt.AlignRight, value)
     
                # restaure les valeurs initiales du painter
                painter.restore() 
     
            else:
                # traitement des cas "normaux"
                QtGui.QStyledItemDelegate.paint(self, painter, option, index)
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        def __init__(self, data=[[]], parent=None):
            super(Fenetre, self).__init__(parent)
            self.resize(800, 600)
     
            # données à traiter: ici, une liste de listes
            self.data = data
     
            # modèle adapté au type de données à traiter
            self.model = QtGui.QStandardItemModel()       
     
            # met les titres des colonnes
            headers = ['col1','col2','col3','col4','col5','col6','col7']
            for j, header in enumerate(headers):
                titrecol = QtGui.QStandardItem(header)
                self.model.setHorizontalHeaderItem(j, titrecol)
     
            # stocke le type de données des colonnes
            self.typecol = [type(elem) for elem in self.data[0]]
     
            # peuple le modèle
            for i, row in enumerate(self.data):
                for j, col in enumerate(row):
                    item = QtGui.QStandardItem()
                    item.setData(col, QtCore.Qt.DisplayRole)
                    self.model.setItem(i, j, item)
     
            # crée le tableau avec son modèle et son delegate
            self.tablevue = QtGui.QTableView(self)
            self.tablevue.setModel(self.model)
            self.tablevue.setItemDelegate(StyleDelegate()) # delegate sous-classé
     
            # ajuste la largeur des colonnes à leur contenu
            self.tablevue.resizeColumnsToContents()
     
            # positionne le tableau dans la fenêtre
            posit = QtGui.QGridLayout()
            posit.addWidget(self.tablevue, 0, 0)
            self.setLayout(posit)
     
        # =======================================================================
        def datasmodif(self):
            """retourne les données modifiées après intervention de l'utilisateur"""
            imax = self.tablevue.model().rowCount()
            jmax = 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 = unicode(item.data(QtCore.Qt.DisplayRole).toString())
                    # conversion selon le type de données de la colonne j
                    if self.typecol[j]==int:
                        elem = int(elem.replace(' ', ''))
                    # ajout
                    data2[-1].append(elem)
            return data2
     
        # =======================================================================
        def keyPressEvent(self, event):
            if self.tablevue.hasFocus():
     
                # déclenché avec Alt-X
                if event.key() == QtCore.Qt.Key_X and \
                                       (event.modifiers() & QtCore.Qt.AltModifier):
     
                    # affiche en console le tableau des données initiales
                    print(self.data)
     
                    # affiche en console le tableau des données modifiées
                    data2 = self.datasmodif()
                    print(data2)
     
                    event.accept()
                else:
                    event.ignore()
            else:
                event.ignore()
     
    #############################################################################
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
     
        data = [[101, "Transfert 1000", 45, 26, 10, 456, 12345678], 
                [102, "Transfert 1001", 45, 26, 10, 456, 23456789], 
                [103, "Transfert 1002", 45, 26, 10, 456, 34567890]]
     
        fen = Fenetre(data)
        fen.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        fen.show()
        sys.exit(app.exec_())

  6. #6
    Membre du Club

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Burkina Faso

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2014
    Messages : 39
    Points : 41
    Points
    41
    Billets dans le blog
    1
    Par défaut
    Merci tyrtamos pour cet exemple au combien aidant, il est temps que je fasse quelque chose que je n'y suis jamais arrivé aupparavant, l'impression... Merci à vous.


    Mais vous n'avez pas une idée de comment reconvertir les nombres transformés en nombre ?

  7. #7
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 480
    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 480
    Points : 9 277
    Points
    9 277
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par kekule10 Voir le message
    comment reconvertir les nombres transformés en nombre ?
    Désolé, mais, formulée comme ça, cette question est incompréhensible: il faut la poser autrement et donner un exemple.

  8. #8
    Membre du Club

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Burkina Faso

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2014
    Messages : 39
    Points : 41
    Points
    41
    Billets dans le blog
    1
    Par défaut
    en fait, je voulais que pour faire le separateur de millier, il fallait transformer le nombre en chaine de caractères, alors je ferais si j'avais besoin de ce nombre transformé que j'ai mis dans un QLineEdit pour un autre traitement? Mais j'ai trouvé comment. Merci

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

Discussions similaires

  1. Séparateur des milliers dans une LISTBOX
    Par LANGAZOU dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 22/01/2015, 21h50
  2. Séparateur des milliers dans les graphiques
    Par Didou139 dans le forum Tableaux - Graphiques - Images - Flottants
    Réponses: 0
    Dernier message: 07/02/2013, 15h16
  3. [IE6] Gérer les séparateurs de milliers dans un input text
    Par ddams dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 12/02/2007, 14h32
  4. séparer les centaines des milliers dans un double
    Par celiaaa dans le forum Access
    Réponses: 5
    Dernier message: 13/12/2006, 13h33
  5. Séparateurs des milliers
    Par blowlagoon dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 26/05/2006, 10h02

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