Search code examples
pythonpyqtpyqt5mouseeventdesktop-application

PyQt5 : close window on right click sends the event to application underneath as well


I have this app where I was trying to close window on right click event, although the event works and my window is closed but the right click is also sent to the app that is present below my python app and therefore a context menu(if present) is opened for that app.

For eg, if I have windows desktop screen below my python app, the context menu of windows will be opened.

enter image description here

This is what I have tried

from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
import sys

class MainWindow(qtw.QMainWindow): 
    
    def __init__(self, *arg, **kwargs):
        super().__init__(*arg, **kwargs)
        
        self.setWindowFlag(qtc.Qt.FramelessWindowHint)
        self.setAttribute(qtc.Qt.WA_TranslucentBackground)
        self.setGeometry(100, 100, 400, 300)
        self.showFullScreen()
        self.setAttribute(qtc.Qt.WA_NoMousePropagation)

        self.show()

    def paintEvent(self, event):
        qp = qtg.QPainter(self)
        qp.setPen(qtg.QPen(qtc.Qt.blue, 1))
        qp.drawRect(self.rect())
        
        qp.setOpacity(0.01)
        qp.setPen(qtc.Qt.NoPen)
        qp.setBrush(self.palette().window())
        qp.drawRect(self.rect())

    # close on right click
    def mousePressEvent(self, QMouseEvent):
        if QMouseEvent.button() == qtc.Qt.LeftButton:
            print("Left Button Clicked")
        elif QMouseEvent.button() == qtc.Qt.RightButton:
            self.close()

if __name__ == '__main__':
    app = qtw.QApplication(sys.argv)
    w = MainWindow()
    sys.exit(app.exec_())

I have tried using WA_NoMousePropagation but that is also not working.

OS: Windows 10
PyQt5==5.15.6
PyQt5-Qt5==5.15.2
PyQt5-sip==12.9.0

Solution

  • On right click of the mouse 2 of the events that gets fired are OnMousePress and OnMouseRelease. Most of the desktop apps and the dektop screen as well responds to the OnMouseRelease event. And since I am closing the window on mousePressEvent. The window is closed but the release event is sent to the application underneath the window. And hence we are seeing the context menu on the application below our app.

    Closing on mouseReleaseEvent worked for me.

    from PyQt5 import QtWidgets as qtw
    from PyQt5 import QtCore as qtc
    from PyQt5 import QtGui as qtg
    import sys
    
    class MainWindow(qtw.QMainWindow): 
        
        def __init__(self, *arg, **kwargs):
            super().__init__(*arg, **kwargs)
            
            self.setWindowFlag(qtc.Qt.FramelessWindowHint)
            self.setAttribute(qtc.Qt.WA_TranslucentBackground)
            self.setGeometry(100, 100, 400, 300)
            self.showFullScreen()
    
            self.show()
    
        def paintEvent(self, event):
            qp = qtg.QPainter(self)
            qp.setPen(qtg.QPen(qtc.Qt.blue, 1))
            qp.drawRect(self.rect())
            
            qp.setOpacity(0.01)
            qp.setPen(qtc.Qt.NoPen)
            qp.setBrush(self.palette().window())
            qp.drawRect(self.rect())
    
        # close on right click
        def mouseReleaseEvent(self, QMouseEvent):
            if QMouseEvent.button() == qtc.Qt.RightButton:
                self.close()
    
    if __name__ == '__main__':
        app = qtw.QApplication(sys.argv)
        w = MainWindow()
        sys.exit(app.exec_())