LeaveEvent of a QTableWidget, not of a QTableWidgetItem



  • Hi everybody :)

    My fisrt topic here !

    I use the mouseMoveEvent of my QTableWidget for view a dialog with a QPixmap from my QPixmapCache.
    With indexAt, I know what item is highlighted and I move my dialog at the QCursor position.
    I doesn't use the tooltip with image because is too long to load many images... With this system is instant.
    To show my dialog, no problem.

    But I need to know when the cursor leave my wydget to hide my dialog.

    So I have tryed to use leaveEvent, but it's called when the cursor leave a QTableWidgetItem...
    I have tryed to watch the HoverLeave event with eventFilter in the QTableWidget's viewport or tryed to use leaveEvent of the parent and send signal. That works if I don't use the mouseMoveEvent of my QTableWidget, if I use this event, the signal is sended and the event is emit when the cursor leave the QTableWidgetItem...

    After many try, I succeeded with the leaveEvent of the parent who test if the QCursor is in or out itself :

    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()
    

    In your opinion, is there any simpler?

    I'm a little programmer, so I don't understant all situation :)

    I program in pyqt5 and sorry for my english !!

    Have a nice day !


  • Lifetime Qt Champion

    Hi,

    Where are you implementing that leaveEvent method ?



  • Hi :)
    In the parent QFrame.
    I have tried with the viewport but it doesn't work everytime...

    My code :

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
    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()
      
    
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
    class ItemTableWidgetCustom(QTableWidget):
        def __init__(self, papa, Parent=None):
            super(ItemTableWidgetCustom, self).__init__(Parent)
     
            ### ............
            self.setMouseTracking(True)
     
            self.BigPapa = Parent
     
            self.papa = papa
            self.papa.mouseLeaveEvent.connect(lambda: self.ToolTipCustom.hide())
     
     
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
        def CreateCacheDialog(self, PixmapCache):
            self.ToolTipCustom = ToolTipCustom(self.BigPapa)
     
            self.PixmapCache = PixmapCache
     
            self.LastIndex = None
     
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
        def mouseMoveEvent(self, event):
            if not self.PixmapCache: return
     
            if self.LastIndex == self.indexAt(event.pos()): return
    
            try:
                Row = self.indexAt(event.pos()).row()
                Column = self.indexAt(event.pos()).column()
                Cell = self.item(Row, Column)
                AlbumId = Cell.data(Qt.UserRole)[0]
     
            except:
                if self.ToolTipCustom.isVisible(): self.ToolTipCustom.hide()
                return
     
            self.LastIndex = self.indexAt(event.pos())
     
            PixmapImage = self.PixmapCache.find(AlbumId)
     
            if PixmapImage:
                self.ToolTipCustom.setPixmap(PixmapImage)
     
                x = QCursor.pos().x() - self.BigPapa.geometry().x() + 10
                y = QCursor.pos().y() - self.BigPapa.geometry().y() + 10
     
                if self.BigPapa.geometry().width() - x - 200 < 0 : x = QCursor.pos().x() - self.BigPapa.geometry().x() - 210
     
                if self.BigPapa.geometry().height() - y - 200 < 0 : y = QCursor.pos().y() - self.BigPapa.geometry().y() - 210
     
               self.ToolTipCustom.move(x, y)
                if not self.ToolTipCustom.isVisible(): self.ToolTipCustom.show()
     
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
    class ToolTipCustom(QLabel):
        def __init__(self, Parent=None):
            super(ToolTipCustom, self).__init__(Parent)
            self.resize(200, 200) 
            self.setScaledContents(True)
    
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
        def enterEvent(self, event):
            self.hide()
    

    and I use :

    self.ui.ItemTableWidgetFrame.__class__ = ItemTableWidgetFrameCustom
     
    self.ui.ItemTableWidget = ItemTableWidgetCustom(self.ui.ItemTableWidgetFrame, self)
     
    self.ui.ItemTableWidgetLayout.addWidget(self.ui.ItemTableWidget)
    

    That works as I want but it can improve, I guess.


  • Lifetime Qt Champion

    Why not use an event filter or directly subclass QTableWidget ?



  • What signal with the eventFiltrer ?
    Because the QEvent::HoverLeave and QEvent::Leave are emit when I leave a QTableWidgetItem, not when I leave the QTableWidget.

    If I subclass the leaveEvent of the QTableWidget, same result.
    But you're right, I can use this event and the geometry test. One widget removed :)


  • Lifetime Qt Champion

    Don't mix signals/slots and events. While they might be related in multithreading context, they are different aspects of Qt.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.