Pavel Pereverzev
Pavel Pereverzev

Reputation: 499

mouse release event on entire screen

I have a pyqt widget that is shown over all windows when launched. I need it to keep unclosed until user decides to. Is that possible to catch mouse release event every time mouseclick performed no matter where it was done: inside QtWidget window or outside of it?

Here is a sample I use:

class Release_check(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()


    def initUI(self):
        self.canvas = iface.mapCanvas()
        self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
        self.grid = QGridLayout()
        self.grid.setSpacing(10)
        self.setGeometry(500, 500, 400, 100)

        self.text_out = QTextEdit()

        self.setLayout(self.grid)
        self.grid.addWidget(self.text_out, 0, 1, 1, 2)

        self.show()


    def mouseReleaseEvent(self, e):
        screen_coordinate = f"x:{e.x()}, y:{e.y()}"
        self.text_out.setText(screen_coordinate)
        super(Release_check, self).mouseReleaseEvent(e)


app = Release_check()

Upvotes: 2

Views: 1121

Answers (1)

eyllanesc
eyllanesc

Reputation: 243897

Qt only detects the click inside the widget, if you want to detect outside the widgets then you must use another library that uses OS resources to monitor OS events such as pyinput:

import sys
from pynput import mouse
from PyQt5 import QtCore, QtGui, QtWidgets


class ButtonReleaseManager(QtCore.QObject):
    released = QtCore.pyqtSignal(int, int)

    def __init__(self, parent=None):
        super().__init__(parent)
        self._listener = mouse.Listener(on_click=self._handle_click)
        self._listener.start()

    def _handle_click(self, x, y, button, pressed):
        if not pressed:
            self.released.emit(x, y)


class Release_check(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.manager = ButtonReleaseManager()
        self.manager.released.connect(self.show_position)

    def initUI(self):
        self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
        self.setGeometry(500, 500, 400, 100)

        self.text_out = QtWidgets.QTextEdit()

        grid = QtWidgets.QGridLayout(self)
        grid.setSpacing(10)
        grid.addWidget(self.text_out, 0, 1, 1, 2)

    @QtCore.pyqtSlot(int, int)
    def show_position(self, x, y):
        screen_coordinate = f"x:{x}, y:{x}"
        self.text_out.setText(screen_coordinate)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = Release_check()
    w.show()
    sys.exit(app.exec_())

Upvotes: 2

Related Questions