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 :

PyQt5 : Afficher les secondes dans un QTableWidget et trier les dates


Sujet :

PyQt Python

  1. #1
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2013
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2013
    Messages : 156
    Points : 218
    Points
    218
    Par défaut PyQt5 : Afficher les secondes dans un QTableWidget et trier les dates
    Salut à tous !

    J'utilise un QTableWidget pour afficher des données.
    La colonne qui me pose probleme contient un QDateTime
    Le problème est que le QTableWidget n'affiche pas les secondes, pourtant que je fait tostring() sur mon item, celui-ci contient bien les secondes. J'ai changer le type pour QTime, idem.
    Le composant bloque donc les secondes d'une quelconque manière.

    Ensuite lorsque j’essaie de trier mes données, les résultats ne sont pas cohérents. Mais c'est peut-être un autre problème

    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
     
    			self.widgetEvents = QtGui.QTableWidget(numberOfEvents, 4);
    			self.widgetEvents.keyPressEvent = self.keyPressOnWidgetEvent;
    			self.setAttribute(QtCore.Qt.WA_AcceptTouchEvents);
    			self.setAttribute(QtCore.Qt.WA_NoMousePropagation);
    			self.widgetEvents.contextMenuEvent = self.contextMenuEvent;
     
    			self.widgetEvents.hide();
    			self.rightPanelUi.verticalLayout.addWidget(self.widgetEvents)
     
    			customHeader = HeaderTableView(QtCore.Qt.Horizontal, self.widgetEvents)
    			customHeader.setStretchLastSection(True)
    			customHeader.setHighlightSections(True)
    			customHeader.setSectionsClickable(True)
    			#customHeader.setSortIndicatorShown(True)
     
    			customHeader.setContextMenuTreeWidgetCallBack(self.getDataToShowAvaillableFilters)
     
    			customHeader.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
    			customHeader.customContextMenuRequested.connect(customHeader.showContextMenu)
     
    			self.widgetEvents.setHorizontalHeader(customHeader)
     
    			self.widgetEvents.setHorizontalHeaderLabels((_('Date'), _('Category'), _('Type'), _('Description')))
     
    			#self.widgetEvents.horizontalHeader().sectionClicked.connect(self.sortData)
    			self.widgetEvents.setSortingEnabled(True)
     
    			self.widgetEvents.verticalHeader().setVisible(False)
    			self.widgetEvents.setAlternatingRowColors(True)
    			self.widgetEvents.setStyleSheet("alternate-background-color: rgb(240,240,240); background-color: white;")
    			self.widgetEvents.setShowGrid(False)
    			self.widgetEvents.hide();
     
    			k = 0; # date & hour
    			for e in eventsLogFramesDecoded:
    				itemDateTime = QTableWidgetItem()
    				#strdatetime = str(e[6]) + '/' + str(e[5]) + '/' + str(2000 + int(e[4])) + ' ' +  str(e[7]) + ':' + str(e[8]) + ':' + str(e[9]);
     
    				date = QDate(2000 + int(e[4]) ,int(e[5]), int(e[6]) )
    				time = QTime(int(e[7]), int(e[8]), int(e[9]))
    				#dateTime = QDateTime(date, time)
    				dateTime = QDateTime(date, time, 1)
     
    				#itemDateTime.setData(0,strdatetime);
    				#itemDateTime.setData(0,  QDateTime(date, time, 1));
    				itemDateTime.setData(0, dateTime);
     
    				self.widgetEvents.setItem(k, 0, itemDateTime);
    				k = k + 1;
    Merci de votre aide !

  2. #2
    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,

    Sans la conversion avec .toString, j'obtiens la même chose: les secondes ne s'affichent pas. Il est possible que ce soit un bug. En principe, le setData d'un QTableWidgetItem devrait accepter un QDateTime intégré dans un QVariant. Mais le QVariant n'existe plus avec PyQt5: il devrait y avoir une conversion automatique par PyQt5 entre C++ et Python, et c'est peut-être ça qui ne marche pas.

    Cependant, avec .toString, ça marche: voir mon code test ci-dessous:

    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
    #!/usr/bin/python  
    # -*- coding: utf-8 -*-  
    # Python 3, PyQt5  
     
    import sys  
    from random import randint
    from PyQt5 import QtCore, QtWidgets  
     
    ############################################################################# 
    class MyTableWidget(QtWidgets.QTableWidget):  
     
        def __init__(self, parent=None):  
            super().__init__(parent)  
     
            nblig, nbcol = 5, 5  
            self.setRowCount(nblig)  
            self.setColumnCount(nbcol)  
     
            for i in range(0, nblig): 
                date = QtCore.QDate(2016 ,randint(1, 12), randint(1, 28))
                time = QtCore.QTime(randint(0,23), randint(0, 59), randint(0, 59))
                dateTime = QtCore.QDateTime(date, time, QtCore.Qt.UTC) 
     
                # conversion en chaine de caractères
                dateTimeStr = dateTime.toString("dd/MM/yyyy hh:mm:ss")           
     
                obj = QtWidgets.QTableWidgetItem()
                obj.setData(QtCore.Qt.DisplayRole, dateTimeStr)
     
                self.setItem(i, 0, obj)
     
    #############################################################################  
    if __name__ == '__main__':  
        app = QtWidgets.QApplication(sys.argv)  
        fenetre = MyTableWidget()  
        fenetre.show()  
        sys.exit(app.exec_())
    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 actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2013
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2013
    Messages : 156
    Points : 218
    Points
    218
    Par défaut
    Bonjour, merci de ta réponse.

    J'ai fait ça pour le moment, mais ça m'embêtai un peu car je vais devoir trier ces données maintenant et que donc je vais devoir ( je pense ) faire des casts intermédiaires pour les dates.

  4. #4
    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
    Une astuce pour trier les dates sous forme de chaine est de redéfinir une nouvelle classe héritant de QTableWidgetItem, et de surcharger sa méthode "__lt__" utilisée par le tri, mais uniquement pour le tri de la colonne concernée (0 dans mon code test).

    Voilà ce que ça peut donner:

    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
    #!/usr/bin/python  
    # -*- coding: utf-8 -*-  
    # Python 3, PyQt5  
     
    import sys  
    from random import randint
    from PyQt5 import QtCore, QtWidgets  
     
    ############################################################################# 
    class TableWidgetItem(QtWidgets.QTableWidgetItem):
     
        def __init__(self, parent=None):  
            super().__init__(parent)  
     
        def __lt__(self, autrevaleur):
     
            if self.column()==0:
     
                v1 = self.data(QtCore.Qt.EditRole)
                dt1 = v1[6:10]+v1[3:5]+v1[0:2]+v1[11:13]+v1[14:16]+v1[17:19]
     
                v2 = autrevaleur.data(QtCore.Qt.EditRole)
                dt2 = v2[6:10]+v2[3:5]+v2[0:2]+v2[11:13]+v2[14:16]+v2[17:19]
     
                return dt1 < dt2
     
            return super().__lt__(autrevaleur)
     
    ############################################################################# 
    class MyTableWidget(QtWidgets.QTableWidget):  
     
        def __init__(self, parent=None):  
            super().__init__(parent)  
     
            nblig, nbcol = 5, 5  
            self.setRowCount(nblig)  
            self.setColumnCount(nbcol)  
     
            self.setSortingEnabled(True)
     
            for i in range(0, nblig): 
                date = QtCore.QDate(2016 ,randint(1, 12), randint(1, 28))
                time = QtCore.QTime(randint(0,23), randint(0, 59), randint(0, 59))
                dateTime = QtCore.QDateTime(date, time, QtCore.Qt.UTC) 
     
                # conversion en chaine de caractères
                dateTimeStr = dateTime.toString("dd/MM/yyyy hh:mm:ss")           
     
                obj = TableWidgetItem() # au lieu de: QtWidgets.QTableWidgetItem()
                obj.setData(QtCore.Qt.DisplayRole, dateTimeStr)
     
                self.setItem(i, 0, obj)
     
    #############################################################################  
    if __name__ == '__main__':  
        app = QtWidgets.QApplication(sys.argv)  
        fenetre = MyTableWidget()  
        fenetre.show()  
        sys.exit(app.exec_())
    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 actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2013
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2013
    Messages : 156
    Points : 218
    Points
    218
    Par défaut
    Intéressant comme solution, je l'avais implémenter différemment, je vais prendre le temps d'analyser ta solution
    Merci à toi !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class DateTableWidgetItem(QtWidgets.QTableWidgetItem):
     
    	def __init__(self, parent = None):
    		super().__init__(parent)
     
    	def __lt__(self, otherItem):
    		thisDate = QDateTime.fromString(self.data(0), "dd/MM/yyyy hh:mm:ss")
    		otherDate = QDateTime.fromString(otherItem.data(0), "dd/MM/yyyy hh:mm:ss")
     
    		return  thisDate.toMSecsSinceEpoch() < otherDate.toMSecsSinceEpoch()

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

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