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

Python Discussion :

QTableWidget sorting numbers


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    ngénieur d'etat en science géodésique et travaux topographique
    Inscrit en
    Septembre 2016
    Messages
    152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : ngénieur d'etat en science géodésique et travaux topographique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2016
    Messages : 152
    Par défaut QTableWidget sorting numbers
    Bonjour,
    avec PYQT5 je crée un QTableWidget qui fonctionne bien. Je veux que l'utilisateur puisse trier chaque colonne, ce qui fonctionne également, mais je n'aime pas la façon dont il trie les colonnes avec des nombres. Il triera les nombres de 0 à 10 comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    0
    1
    10
    2
    3
    4
    5
    6
    7
    8
    9
    Mais je le veux comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

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

    Sans modification, un QTableWidget ne contient que des chaînes de caractères, et c'est ce que le 1er tri montre bien. Or, tu veux un tri numérique.

    Pour obtenir le tri purement numérique, il suffit de convertir en entier. Mais tout dépend ce que tu veux obtenir: tu peux facilement trier une extraction de la colonne (.sort(key=lambda v: int(v))), mais si tu veux obtenir le tri numérique en cliquant simplement en haut de sa colonne, c'est un peu plus compliqué.

    Il y a plusieurs solutions, mais celle que j'utilise pour ça est de sous-classer QTableWidgetItem, et de surcharger sa méthode '__lt__' (=less than) pour la colonne concernée. Il faut être sûr que cette colonne ne contienne que des nombres entiers, sinon il faudra gérer les cas différents pour éviter un plantage avec la conversion int(...).

  3. #3
    Membre confirmé
    Homme Profil pro
    ngénieur d'etat en science géodésique et travaux topographique
    Inscrit en
    Septembre 2016
    Messages
    152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : ngénieur d'etat en science géodésique et travaux topographique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2016
    Messages : 152
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Bonjour,
    , mais si tu veux obtenir le tri numérique en cliquant simplement en haut de sa colonne, c'est un peu plus compliqué.
    .
    C'est ce que je recherche

  4. #4
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 190
    Par défaut
    hello,
    en utilisant le code de tyrtamos qui se trouve ici tu peux essayer d'utiliser la fonction suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    def _human_key(key):    
        parts = re.split('(\d*\.\d+|\d+)', key)
        return tuple((e.swapcase() if i % 2 == 0 else float(e))
                for i, e in enumerate(parts))
    utilisation dans le code de tyrtamos :
    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
     
    class TableWidgetItem(QtWidgets.QTableWidgetItem): 
        # =======================================================================
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
     
            self.pasdetricols = []
     
        # =======================================================================
        def __lt__(self, other):
     
            if self.column() in self.pasdetricols:
                return False
            else:
                a = self.data(QtCore.Qt.DisplayRole)
                b = other.data(QtCore.Qt.DisplayRole)
                return (_human_key(a) < _human_key(b))
    Nom : SortQtTableWidget.gif
Affichages : 799
Taille : 37,2 Ko

    Ami calmant, J.P

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    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 486
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par rabeh.ram Voir le message
    C'est ce que je recherche
    Voilà un petit code de test qui fait ça:

    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
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
     
    import sys
    from random import randint
    from PyQt5 import (QtWidgets, QtGui, QtCore)
     
     
    #############################################################################
    class TableWidgetItem(QtWidgets.QTableWidgetItem):
     
        # =======================================================================
        def __init__(self, numcol):
            super().__init__()
     
            self.numcol = numcol
     
        # =======================================================================
        def __lt__(self, other):
     
            if self.column()==self.numcol:
                a = self.data(QtCore.Qt.DisplayRole)
                b = other.data(QtCore.Qt.DisplayRole)
                return (int(a) < int(b))
            else:
                # autres colonnes
                return super().__lt__(other)
     
    #############################################################################
    class Fenetre(QtWidgets.QWidget):
     
        # =======================================================================
        def __init__(self, parent=None):
            super().__init__(parent)
     
            self.resize(600, 300)
     
            self.tableWidget = QtWidgets.QTableWidget(self)
            self.nbrow, self.nbcol = 5, 5
            self.tableWidget.setRowCount(self.nbrow)
            self.tableWidget.setColumnCount(self.nbcol)
            self.tableWidget.setSortingEnabled(True)
            self.tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)  # MultiSelection) 
     
            # numéro de colonne avec tri numérique
            self.numcol = 3
     
            # peuple le QTableWidget
            for row in range(0, self.nbrow):
                for col in range(0, self.nbcol):
                    item = TableWidgetItem(self.numcol)
                    val = str(randint(5, 15))    
                    item.setData(QtCore.Qt.DisplayRole, val)
                    self.tableWidget.setItem(row, col, item)
     
            posit = QtWidgets.QGridLayout()
            posit.addWidget(self.tableWidget, 0, 0)
            self.setLayout(posit)
     
            self.tableWidget.setFocus()
            self.tableWidget.setCurrentCell(0, 0)
     
    #############################################################################
    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())
    On voit que quand on demande le tri en cliquant sur la colonne de titre "4" (=indice 3), que le tri numérique est correct, ce qui n'est pas le cas dans les autres colonnes.

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 812
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    On voit que quand on demande le tri en cliquant sur la colonne de titre "4" (=indice 3), que le tri numérique est correct, ce qui n'est pas le cas dans les autres colonnes.
    Pourquoi ne trier que la numcol=3 ? On enlève le paramètre "numcol" ainsi que le test de la ligne 21 et tout clic sur n'importe quelle colonne la trie comme il faut non ?
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

    Citation Envoyé par Sve@r Voir le message
    Pourquoi ne trier que la numcol=3 ? On enlève le paramètre "numcol" ainsi que le test de la ligne 21 et tout clic sur n'importe quelle colonne la trie comme il faut non ?
    J'ai traité le cas général dans lequel une seule colonne doit être triée numériquement. Les autres colonnes sont triées comme des chaines de caractères et ça permet de voir la différence, ce qui répond exactement à la question du PO.

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 812
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par rabeh.ram Voir le message
    mais je n'aime pas la façon dont il trie les colonnes avec des nombres. Il triera les nombres de 0 à 10 comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    0
    1
    10
    2
    3
    4
    5
    6
    7
    8
    9
    Oui, parce que la string "10" est plus grande que la string "1" mais plus petite que la string "2"...
    Et il existe une section dédiée PyQt sur ce forum.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. QTableWidget sort disable
    Par rabeh.ram dans le forum PyQt
    Réponses: 2
    Dernier message: 01/05/2020, 18h16
  2. StringGrid sort
    Par clovis dans le forum C++Builder
    Réponses: 4
    Dernier message: 20/10/2004, 21h46
  3. format-number()
    Par Pierre63 dans le forum XMLRAD
    Réponses: 5
    Dernier message: 11/07/2003, 17h58
  4. xsl:sort
    Par Pierre63 dans le forum XMLRAD
    Réponses: 2
    Dernier message: 03/07/2003, 12h37
  5. JBuilder 7 personnal sort à chaque save
    Par Hannouz dans le forum JBuilder
    Réponses: 4
    Dernier message: 17/12/2002, 22h53

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