10

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!

Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
Phil
  • 13,875
  • 21
  • 81
  • 126
  • 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. – Andreas Fester Dec 30 '12 at 14:57
  • 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 Dec 30 '12 at 15:15

2 Answers2

18

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_())
  • 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. – Phil Dec 30 '12 at 19:33
  • @Phil Checkout my [updated answer](http://stackoverflow.com/a/14092099/1006989), I added another example to check the mouse position –  Dec 30 '12 at 19:44
  • 2
    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. – Phil Dec 30 '12 at 19:46
12

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

David Lannan
  • 169
  • 2
  • 5