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

16,730

Solution 1

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

Solution 2

underMouse() is what should be used to determine whether your mouse is over a widget.
Usage: widget.underMouse()
http://pyqt.sourceforge.net/Docs/PyQt4/qwidget.html#underMouse

Share:
16,730
Phil
Author by

Phil

Updated on June 05, 2022

Comments

  • Phil
    Phil almost 2 years

    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!

    • Andreas Fester
      Andreas Fester over 11 years
      Can you provide some more code, ideally with a complete sample which shows your issue? If you override event methods for a widget, they are implicitly called for this widget, unless you grab the mouse.
    • Phil
      Phil over 11 years
      Hello Andreas. If you click a widget, keep your mouse down but drag the cursor over to another widget away from this when you release your mouse, mouseReleaseEvent is still triggered. I need to know at the time of release if the cursor is over the widget. How can I do this?
  • Phil
    Phil over 11 years
    Hello @X.Jacobs. Thank you for this answer very much. It did not solve my issue exactly due to drag actions (when mouse is down) fail underMouse() method. But taking cue from your post and doing bit more research I implemented a conditional to mouseReleaseEvent. What I did is, get relative mouse position using event.pos() and check its .x() and .y() values against width and height of the widget. if the position are within the boundaries, I continued with the event if not halted it.
  • Admin
    Admin over 11 years
    @Phil Checkout my updated answer, I added another example to check the mouse position
  • Phil
    Phil over 11 years
    Hi @X.Jacobs. This is very exciting! Your solution is hell of a lot more elegant than my pitiful hack. ;-) Excellent! You rock! I really truly appreciate ALL your help.
  • developer01
    developer01 over 2 years
    Worked for me as well. Thanks.