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 :

Un leaveEvent sur un QTableWidget ?


Sujet :

PyQt Python

  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut Un leaveEvent sur un QTableWidget ?
    Bonjour à vous

    Je vous explique en gros mon système :
    - Un QPixmapCache qui contient pas mal d'images
    - Un QTableWidget qui contient pas mal d'items
    - Un QDialog qui me servira de tooltip pour afficher les Pximap du cache

    Via mouseMoveEvent de la classe du QTableWidget je récupère l'item survolé et j'affiche le QDialog avec le QPixmap.

    Je voudrais savoir quand la souris quitte le QTableWidget, et ça je n'y arrives pas très bien.

    Car leaveEvent est appelé entre les items également...

    J'ai essayé de jouer avec le viewport du QTableWidget mais c'était la même chose.
    Via un eventFilter, j'arrive à voir quand la souris s'en va mais sans différenciation entre quitter un item et quitter le QTableWidget (c'est ce que je fais actuellement mais si je cache la fenêtre à chaque fois, ça fait qu'elle se ferme après être rentrée dans un autre item, du coup ça ne fonctionne pas).

    Après je me dis que si je mets un widget parent, je peux surveiller le leaveEvent dessus et envoyé un signal au QTableWidget...

    Du coup :
    - A votre avis, quelle est la meilleur façon de faire ?
    - Avez vous une idée simple pour utiliser le toolTip des QTablesWidgetItem directement depuis un QPixmap ? (j'ai essayé de suivre ta procédure Tyrtamos mais ça semblait beaucoup moins réactif)
    Et question annexe, je ne retrouve plus comment indiquer à une QDialog de ne pas apparaître dans la barre des taches... Savez vous comment on fait ?

    Merci et bonne journée à vous !
    Sous Kubuntu 20.04

  2. #2
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    J'ai réussis à utiliser les tooltips ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Img = self.PixmapCache.find("Mon image du cache")
    if Img:
      buffer = QBuffer()
      buffer.open(QIODevice.WriteOnly)
      Img.save(buffer, "PNG", quality=100)
      image = bytes(buffer.data().toBase64()).decode()
      html = '<img src="data:image/png;base64,{}">'.format(image)
      widget.setToolTip(html)
    Mais le soucis c'est que c'est vachement lourd à charger...

    alors que si je fais le chargement du QPixmap en direct, c'est instantané...

    je sais qu'il y a moyen de surclasser l'event du tooltip mais pas sur que ce soit pratique pour sa fermeture...

    EDIT :
    Je viens d'essayer de passer par un QFrame parent pour envoyer un signal prévenant le QTableWidget que la souris est partie, mais vu que le QTable est l'enfant du QFrame, le système d’héritage fout le bordel.
    Le QFrame envoie l'information à chaque changement d'item...
    Comment peut on éviter cela ?!
    Merci à vous.
    Sous Kubuntu 20.04

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    Bon bah je continue mon monologue :p

    j'ai réussi à faire ce que je voulais mais je me demande s'il n'y a pas plus simple...

    J'utilise le leaveEvent du parent qui teste si le curseur est à l'intérieur ou à l’extérieur de lui même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class ItemTableWidgetFrameCustom(QFrame):
        mouseLeaveEvent = pyqtSignal()
     
        def leaveEvent(self, event):
            widgetRect = self.geometry()
            widgetRect.moveTopLeft(self.parentWidget().mapToGlobal(widgetRect.topLeft()))
     
            if not widgetRect.contains(QCursor.pos()):
                self.mouseLeaveEvent.emit()
     
            event.accept()
    et lorsque le QTableWidget reçoit ce signal, il cache la fenêtre tooltip maison.

    Je voulais le faire sur le viewport du QTableWidget mais ça ne fonctionne pas à tous les coups...

    Il faut encore que j'arrive à faire en sorte que la fenêtre n’apparaisse pas dans la barre des taches.
    Sous Kubuntu 20.04

  4. #4
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    Et hop, je vais clôturer mon topic tout seul comme un grand alors

    voici ce que j'ai fait au final :
    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
     
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
    #~ Classe du parent du QTableWidget le prevenant quand la souris est partie ~#
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
    class ItemTableWidgetFrameCustom(QFrame):
        ### Signal qui sera envoyé quand le curseur quitte le parent
        mouseLeaveEvent = pyqtSignal()
     
        def leaveEvent(self, event):
            """Fonction appelée quand le curseur quitte un QTableWidget ou le widget (parent du QTableWidget)."""
            ### Récupération de l'emplacement du widget(parent du QTableWidget)
            widgetRect = self.geometry()
            widgetRect.moveTopLeft(self.parentWidget().mapToGlobal(widgetRect.topLeft()))
     
            ### Si le curseur n'est plus dedans, on envoie le signal au QTableWidget
            if not widgetRect.contains(QCursor.pos()):
                self.mouseLeaveEvent.emit()
     
            ### Acceptation de l'event
            event.accept()
     
     
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
    #~~~~~~~~~~~~~~~~~~~~~~ Classe de la liste des items ~~~~~~~~~~~~~~~~~~~~~~~~#
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
    class ItemTableWidgetCustom(QTableWidget):
        def __init__(self, papa, Parent=None):
            super(ItemTableWidgetCustom, self).__init__(Parent)
     
            ### Configuration du QTableWidget
            ............
            self.setMouseTracking(True)
     
            ### Permettra d'indiquer le parent à la tooltip maison
            self.BigPapa = Parent
     
            ### Création du lien avec le widget parent qui recevra un signal lors du départ du curseur
            self.papa = papa
            self.papa.mouseLeaveEvent.connect(lambda: self.ToolTipCustom.hide())
     
     
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
        def CreateCacheDialog(self, PixmapCache):
            """Chargement de la tooltip maison."""
            ### Chargement de la tooltip maison avec le parent
            self.ToolTipCustom = ToolTipCustom(self.BigPapa)
     
            ### Réccupération du QPixmapCache
            self.PixmapCache = PixmapCache
     
            ### Création d'une variable partagée
            self.LastIndex = None
     
     
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
        def mouseMoveEvent(self, event):
            """Surcharge le survol des items."""
            ### S'il n'y a pas d'image dans le cache
            if not self.PixmapCache: return
     
            ### Si l'index est le même que le précédent
            if self.LastIndex == self.indexAt(event.pos()): return
     
            ### Récupération des infos de l'item survolé
            try:
                Row = self.indexAt(event.pos()).row()
                Column = self.indexAt(event.pos()).column()
                Cell = self.item(Row, Column)
                AlbumId = Cell.data(Qt.UserRole)[0]
     
            ### S'il n'y a pas d'item sous le curseur
            except:
                if self.ToolTipCustom.isVisible(): self.ToolTipCustom.hide()
                return
     
            ### Mise à jour de la variable index
            self.LastIndex = self.indexAt(event.pos())
     
            ### Récupération de l'image
            PixmapImage = self.PixmapCache.find(AlbumId)
     
            ### Modification de l'image et affichage de la fenêtre
            if PixmapImage:
                ## Modification de l'image
                self.ToolTipCustom.setPixmap(PixmapImage)
     
                ## Calcul de l'emplacement ou afficher la toolTip, car on ne se réfère pas à l’écran mais à la fenêtre principale et on décale l'image pour ne pas qu'elle gène la souris
                x = QCursor.pos().x() - self.BigPapa.geometry().x() + 10
                y = QCursor.pos().y() - self.BigPapa.geometry().y() + 10
     
                ## Si l'image va être coupée en largeur, on modifie son emplacement pour qu'elle soit à gauche du curseur
                if self.BigPapa.geometry().width() - x - 200 < 0 : x = QCursor.pos().x() - self.BigPapa.geometry().x() - 210
     
                ## Si l'image va être coupée en hauteur, on modifie son emplacement pour qu'elle soit au dessus du curseur
                if self.BigPapa.geometry().height() - y - 200 < 0 : y = QCursor.pos().y() - self.BigPapa.geometry().y() - 210
     
                ## Déplacement de l'image à l'endroit voulu
                self.ToolTipCustom.move(x, y)
     
                ## Affichage de la fenêtre si elle n'est pas déjà visible
                if not self.ToolTipCustom.isVisible(): self.ToolTipCustom.show()
     
     
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
    #~~~~~~~~~ Classe de la toolTip maison contenant l'image de l'album ~~~~~~~~~#
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
    class ToolTipCustom(QLabel):
        """Fenêtre de configuration du code."""
        def __init__(self, Parent=None):
            super(ToolTipCustom, self).__init__(Parent)
     
            ### Taille de l'image
            self.resize(200, 200)
     
            ### Adaptation de l'image
            self.setScaledContents(True)
     
        def enterEvent(self, event):
            """Surcharge de l'event d'entrée de la souris dans la fenêtre."""
            ### On cache l'image si la souris est arrivée dessus
            self.hide()
    et on appelle le tout :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
            ### Mon ItemTableWidgetFrame a été créé via Qt Designer, je lui attribue la class créée manuellement
            self.ui.ItemTableWidgetFrame.__class__ = ItemTableWidgetFrameCustom
     
            ### Création du QTableWidget avec son parent et la fenêtre principale
            self.ui.ItemTableWidget = ItemTableWidgetCustom(self.ui.ItemTableWidgetFrame, self)
     
            ### Ajout du QTableWidget dans mon Layout créé sous Qt Designer
            self.ui.ItemTableWidgetLayout.addWidget(self.ui.ItemTableWidget)
    Voilou, en espérant que ça serve à quelqu'un

    Bon week end à ceux qui auront eu le courage de me lire :p
    Sous Kubuntu 20.04

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

Discussions similaires

  1. Ouvrir un fichier CSV sur un QTableWidget
    Par lekev262 dans le forum PyQt
    Réponses: 0
    Dernier message: 01/08/2014, 22h17
  2. Segmentation fault sur QTableWidget
    Par chrtophe dans le forum Débuter
    Réponses: 0
    Dernier message: 28/12/2012, 21h02
  3. QTableWidget::findItems sur les éléments sélectionnés
    Par chrtophe dans le forum Débuter
    Réponses: 2
    Dernier message: 03/07/2012, 09h08
  4. Réponses: 1
    Dernier message: 18/01/2012, 22h32
  5. Réponses: 4
    Dernier message: 11/12/2011, 20h29

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