Reputation: 799
I just noticed that moving the mouse cursor across a tooltip does not seem to return a mouseMoveEvent in PySide.
In my case it causes trouble as I am dynamically displaying a mini-icon on top of a main icon when the mouse moves over the main icon area, and hiding the mini-icon again when the mouse leaves the main icon area. So if the user moves the mouse cursor across a large tooltip and then ends up outside the main button area, the mouse event never registered the new position and the mini-icon stays visible, even though the mouse is no longer over the main icon area.
I guess I could work around this problem by creating a custom QToolTip and positioning it away from the main button area, so it's never possible to leave the main button area via the tooltip. But that seems ugly.
Does anybody have an idea how to make the tooltip register with mouseMoveEvent so thie can be avoided?
Here is an example snippet (hope it will be formatted right, I have never posted here before):
import sys
from PySide.QtGui import *
from PySide.QtCore import *
class FancyButtonSmall( QWidget ):
def __init__( self, parent=None ):
super( FancyButtonSmall, self ).__init__( parent )
self.setMouseTracking( True ) # TO DISPLAY "REMOVE" ICON ON MOUSE OVER
# LAYOUT
layout = QVBoxLayout()
layout.setSpacing( 0 )
self.setLayout( layout )
self.setSizePolicy( QSizePolicy.Fixed, QSizePolicy.Fixed )
self.fixedSize = ( 80, 80 )
# BUTTON AND MOUSE STATE
self.mainButtonDown = False # TO DRAW ICON STATE PROPERLY
self.removeButtonDown = False # TO DRAW ICON STATE PROPERLY
self.mouseOver = False # TO DISPLAY DELETE ICON
# BUTTON COLOURS
self.widgetColMainUp = QColor(60, 60, 60, 0)
# LABELS
self.textCol = QColor( 150, 150, 150 )
# TOOLTIP
self.setToolTip( self.__wrapText( 100*'test ' ) )
def __wrapText( self, text, maxChar = 50 ):
'''wrap text to only contain maxChar per line'''
i = 1
charList = list( text )
while i*maxChar < len( charList ):
charList.insert( i*maxChar, '\n' )
i += 1
return ''.join( charList )
def mouseMoveEvent( self, event ):
'''Show remove icon if cursor is on top of main icon'''
print event.pos()
self.mouseOver = self.iconRect.contains( event.pos() ) or self.removeIconRect.contains( event.pos() )
self.update()
def paintEvent( self, event ):
painter = QPainter( self )
painter.setRenderHint( QPainter.Antialiasing )
# ICONS
self.mainRect = QRect( 0, 0, self.geometry().width(), self.geometry().height() )
iconSize = QSize( 58,58 )
iconPos = QPoint( ( self.mainRect.width()-iconSize.width())/2, 10 )
self.iconRect = QRect( iconPos, iconSize)
removeIconSize = QSize( 16, 16 )
removeIconPos = QPoint( iconSize.width()+iconPos.x()-10, iconPos.y()-5 )
self.removeIconRect = QRect( removeIconPos, removeIconSize )
# DRAW ICONS
self.drawIcon( painter, iconPos, iconSize )
# DRAW REMOVE ICON
if self.mouseOver:
self.drawIcon( painter, removeIconPos, removeIconSize, 'remove' )
def drawIcon( self, painter, pos, size, btn='main' ):
'''Draw icon with status'''
painter.drawRect( pos.x(), pos.y(), size.width(), size.height() )
def minimumSizeHint( self ):
return QSize( *self.fixedSize )
def sizeHint( self ):
return QSize( *self.fixedSize )
if __name__ == '__main__':
import os
app = QApplication( sys.argv )
w = QWidget()
w.setLayout( QGridLayout() )
btn2 = FancyButtonSmall()
w.layout().addWidget( btn2, 1, 0 )
w.show()
sys.exit( app.exec_() )
Upvotes: 0
Views: 1029
Reputation: 799
One of those moments where the answer becomes apparent right after asking: using enterEvent() and leaveEvent() instead of mouseMoveEvent() works a treat.
Upvotes: 0