Search code examples
c++qtpyqtpysideqwidget

How can I know if the mouse is over the widget?


I am fairly new to Qt (PyQt - PySide).
I am trying to build a custom widget which is a menu. However I have hit a hard road and I can not seem to be able to sort myself out. I've read the documentation but I don't think there is a mouse state I can verify to find out if mouse cursor is over the given widget.

I am calling a function upon the mouseReleaseEvent of a QWidget.

Ex.:

def mouseReleaseEvent(self, e):     

When this event is triggered, I have to know if the mouse is actually over the widget or outside of it (the widget of which this event is triggered).

    if mouseCursorOverSelf == True:
        # do something ..

How can I achieve this? What do I need to do?

Thank you very much!


Solution

  • If you want to keep track of when the mouse enters or leaves the widget you can use something like this:

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    
    from PyQt4 import QtCore, QtGui
    
    class mainwindow(QtGui.QWidget):
        def __init__(self, parent=None):
            super(mainwindow, self).__init__(parent)
    
        def enterEvent(self, event):
            print "Mouse Entered"
            return super(mainwindow, self).enterEvent(event)
    
        def leaveEvent(self, event):
            print "Mouse Left"
            return super(mainwindow, self).enterEvent(event)
    
    if __name__ == "__main__":
        import sys
    
        app  = QtGui.QApplication(sys.argv)
        main = mainwindow()
        main.show()
        sys.exit(app.exec_())
    

    If you just want to check whether the mouse is over the widget, you can use the QWidget::underMouse () function:

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    
    from PyQt4 import QtCore, QtGui
    
    class mainwindow(QtGui.QWidget):
        def __init__(self, parent=None):
            super(mainwindow, self).__init__(parent)
    
            self.button = QtGui.QPushButton("Check Mouse in 3 seconds")
            self.button.clicked.connect(self.on_button_clicked)
    
            self.layout = QtGui.QHBoxLayout(self)
            self.layout.addWidget(self.button)
    
        def mouseReleaseEvent(self, event):  
            if self.underMouse():
                print "Do something"
    
            return super(mainwindow, self).mouseReleaseEvent(event)
    
        @QtCore.pyqtSlot()
        def on_button_clicked(self):    
            QtCore.QTimer.singleShot(3000, self.checkMouse)
    
        def checkMouse(self):
            print "Under Mouse: {0}".format(self.underMouse())
    
    if __name__ == "__main__":
        import sys
    
        app  = QtGui.QApplication(sys.argv)
        main = mainwindow()
        main.show()
        sys.exit(app.exec_())
    

    Another method would involve checking if the position of the mouse is within the internal geometry of the widget:

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    
    from PyQt4 import QtCore, QtGui
    
    class mainwindow(QtGui.QWidget):
        def __init__(self, parent=None):
            super(mainwindow, self).__init__(parent)
    
            self.setMouseTracking(True)
    
        def mouseReleaseEvent(self, event):  
            posMouse =  event.pos()
            if self.rect().contains(posMouse):
                print "Under Mouse"
    
            return super(mainwindow, self).mouseReleaseEvent(event)
    
    if __name__ == "__main__":
        import sys
    
        app  = QtGui.QApplication(sys.argv)
        main = mainwindow()
        main.show()
        main.resize(200, 200)
        sys.exit(app.exec_())