Catch the mouse event

1.1k Views Asked by At

Don't know exactly how to give the parameters of QMouseEvent class. Should I create new class to implement a QMouseEvent into my QTextEdit?

class Test(QMainWindow):
    def __init__(self):
        super().__init__()

        self.txt = QTextEdit(self)
        self.txt.setMouseTracking(True)
        
        self.txt.mouseReleaseEvent(QMouseEvent())

class Test2(QTextEdit):
    def __init__(self):
        super().__init__()

    def mouseReleaseEvent(self, e):
        print("text edit is clicked")

ui = Test()
ui.show()
1

There are 1 best solutions below

0
On BEST ANSWER

Since many times it is asked how to detect the events that affect a widget then in this answer I will detail the solution and it will be used as a canonical answer for future questions.

To detect an event from a widget there are several solutions:

- Override a method

If the widget has a method that handles that event then an option is to override that method and associate it with a signal so that other objects can be notified.

In the particular case of the mouse release event, this is handled by the mouseReleaseEvent method.

from PyQt5 import QtCore, QtWidgets


class TextEdit(QtWidgets.QTextEdit):
    released = QtCore.pyqtSignal()

    def mouseReleaseEvent(self, event):
        super().mouseReleaseEvent(event)
        self.released.emit()


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.textedit = TextEdit()
        self.textedit.released.connect(self.handle_released)
        self.setCentralWidget(self.textedit)

    @QtCore.pyqtSlot()
    def handle_released(self):
        print("released")


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

- Use an event filter

Qt allows you to monitor the events using an event filter, so you can take advantage of this feature to emit a signal in a similar way to the previous solution.

In the case of classes that inherit from QAbstractScrollArea, the mouse methods are transmitted to the viewport, so that object must be monitored.

from PyQt5 import QtCore, QtWidgets


class ReleaseFilter(QtCore.QObject):
    released = QtCore.pyqtSignal()

    def __init__(self, widget):
        super().__init__(widget)
        self._widget = widget
        self.widget.installEventFilter(self)

    @property
    def widget(self):
        return self._widget

    def eventFilter(self, obj, event):
        if obj is self.widget and event.type() == QtCore.QEvent.MouseButtonRelease:
            self.released.emit()
        return super().eventFilter(obj, event)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.textedit = QtWidgets.QTextEdit()
        rf = ReleaseFilter(self.textedit.viewport())
        rf.released.connect(self.handle_released)
        self.setCentralWidget(self.textedit)

    @QtCore.pyqtSlot()
    def handle_released(self):
        print("released")


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())