1

I'd like to intercept an event from a widget placed on-top of another widget, without consuming it.

Here's what I've got so far. When clicking the overlapping part, I'd like it to print "Hello World", but all I'm getting is "Hello".

image

import sys
from PyQt5 import QtWidgets


class Button(QtWidgets.QPushButton):
    def mousePressEvent(self, event):
        print self.text()
        return super(Button, self).mousePressEvent(event)


app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()
window.setFixedSize(200, 100)

button1 = Button("World", window)
button1.move(10, 10)
button2 = Button("Hello", window)
button2.move(50, 15)

window.show()
app.exec_()

Here's an example in QML that does what I'm looking for.

image

import QtQuick 2.0


Item {
    id: root
    width: 200; height: 100

    MouseArea {
        anchors.fill: parent
        onPressed: console.log("World")
    }

    Rectangle {
        color: "green"
        width: 100; height: 50
        x: 10; y: 10

        MouseArea {
            anchors.fill: parent
            propagateComposedEvents: true
            onPressed: {
                console.log("Hello");
                mouse.accepted = false;
            }
        }
    }
}

Clicking the window yields "World" whereas clicking the green rectangle yields "Hello" followed by "World". The key here is the propagateComposedEvents

Marcus Ottosson
  • 3,241
  • 4
  • 28
  • 34
  • Hi, I am writting for clarifying, did you ever got this problem solved, "propagate an event from overlapping widgets"? I have a similar case [link](https://stackoverflow.com/questions/62707764/propagate-mouse-events-from-qgraphics-scene-to-qtwebenginewidgets-qwebengineview) – MBV Jul 03 '20 at 04:07
  • 1
    Ooo, not sure. It was a while ago, I think this might be it: https://stackoverflow.com/a/27417852/478949 – Marcus Ottosson Jul 03 '20 at 11:38

1 Answers1

0

There's a window attribute which does what you want:

button = Button("Hello", window)
button.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • Thanks, but I think you may have misread the question. I'm not looking for it to *ignore* "Hello", I'd like it to print both "Hello" *and* "World"; i.e. for the overlapping widget to receive the event, but also pass it on to any widget residing directly under it. – Marcus Ottosson Dec 07 '14 at 11:12
  • @MarcusOttosson. Fair enough, but your question is very misleading (and self-contradictory) - in particular, where you say "the top-most widget should be completely transparent - i.e. have no impact on the underlying widgets". Also, the example code seems flawed and hides the actual intent expressed in the tracker issue. (It's generally not a good idea to link to off-site resources in SO questions: always try to put all the relevant information in the question itself). – ekhumoro Dec 07 '14 at 17:18
  • Sorry about that, @ekhumoro, you're welcome to edit the question if you find a better expression of it. I felt it necessary to add the "transparency" note, as someone might otherwise suggest installing event filters onto each underlying widget, or otherwise manually propagate via `QApplication.postEvent`. Editing the question now. – Marcus Ottosson Dec 08 '14 at 08:03