PyQt4 MouseMove event without MousePress

Anti Earth picture Anti Earth · Oct 20, 2011 · Viewed 18k times · Source

I need to catch when a User moves the mouse over the GUI, but not when they're holding down the mouse button (which would do something different).

I can't find any conveniant method to do this, except to periodically find the mouse position and check it to it's previous position... Which would suck.

The mouseMoveEvent is only called when the mouse is moved whilst the left mouse button is pressed, unless ofcourse the widget has 'mouse tracking'. Mouse tracking is not an option for me, because the GUI must behave differently when the mouse is moved and the left mouse button is pressed.

Are there any inbuilt methods to do this? (or just any clever ideas?)

eg: Is there a way to check if the left mouse button is being pressed at any time?
Or a 'mouse hover' event that can be applied to a QRect (coordinates)?

Muchas gracias.


Windows 7 (32)
python 2.7
PyQt4

Answer

ekhumoro picture ekhumoro · Oct 20, 2011

The most straightforward way to do this is to install an event filter on qApp:

from PyQt4 import QtGui, QtCore

class Window(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        widget = QtGui.QWidget(self)
        layout = QtGui.QVBoxLayout(widget)
        self.edit = QtGui.QLineEdit(self)
        self.list = QtGui.QListWidget(self)
        layout.addWidget(self.edit)
        layout.addWidget(self.list)
        self.setCentralWidget(widget)

    def eventFilter(self, source, event):
        if event.type() == QtCore.QEvent.MouseMove:
            if event.buttons() == QtCore.Qt.NoButton:
                pos = event.pos()
                self.edit.setText('x: %d, y: %d' % (pos.x(), pos.y()))
            else:
                pass # do other stuff
        return QtGui.QMainWindow.eventFilter(self, source, event)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    win = Window()
    win.show()
    app.installEventFilter(win)
    sys.exit(app.exec_())