I have two overlapping widgets in a window child A and child B. Child A is above B and gets mouse events but sometimes the click should pass through and eventually hit child B.
The ideal solution would have been to use event->ignore()
but this passes the event to the parent widget, not siblings.
The "pass all" solution setAttribute(Qt::WA_TransparentForMouseEvents);
does not work either because child A needs to capture some events.
How do I tell Qt "I do not want to handle this event, act like I am not there" ?
The easier solution (if applicable) is to set WA_TransparentForMouseEvents
depending on your click-through condition.
For example, if you want to click through certain regions of Child-A, you can use its mouseMoveEvent()
to check whether WA_TransparentForMouseEvents
needs to be set or unset. Then click events pass through automatically.
If you cannot determine whether a click event should be accepted before it has actually been triggered, you can do something like this:
void ChildA::mousePressEvent(QMouseEvent* event) {
const bool accepted = ...; //insert custom logic here
if (accepted) {
... //handle event here
} else {
//not accepting event -> resend a copy of this event...
QMouseEvent* eventCopy = new QMouseEvent(*event);
QApplication::instance()->postEvent(eventCopy);
//...but this time, ignore it
setAttribute(Qt::WA_TransparentForMouseEvents, true);
QTimer::singleSlot(1, this, SLOT(resetClickTransparency()));
//don't propagate original event any further
event->accept();
}
}
void ChildA::resetClickTransparency() { //slot
setAttribute(Qt::WA_TransparentForMouseEvents, false);
}
Disclaimer: All of this written down by heart after a year of not doing Qt, so please correct me on name or type errors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With