Fist, apologies for the length of the question.
I am trying to propagate custom Qt event from child widgets to a top parent widget in order to trigger some action based on event type instead of linking signals.
Qt docs suggests that every event posted with postEvent()
that have accept()
and ignore()
methods can be propagated (meaning each QEvent
subclass).
I have tried to override customEvents
method instead of events
but to no avail.
Python
I've tried this in Python using PyQt4 (Qt version is 4.6).
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class Foo(QWidget):
def doEvent(self):
QApplication.postEvent(self, QEvent(12345))
def event(self, event):
event.ignore()
return False
class Bar(QWidget):
def __init__(self, *args, **kwargs):
super(Bar, self).__init__(*args, **kwargs)
self.foo = Foo(self)
layout = QHBoxLayout()
layout.addWidget(self.foo)
self.setLayout(layout)
def event(self, event):
if event.type() == 12345:
self.someEventHandler()
return True
def someEventHandler(self):
print 'Handler in {0}'.format(self.__class__.__name__)
if __name__=='__main__':
app = QApplication([''])
bar = Bar()
bar.show()
bar.foo.doEvent()
app.exec_()
In this example Bar.someEventHandler()
would only trigger if event was posted with self.parent()
as the first argument like so:
def doEvent(self):
QApplication.postEvent(self.parent(), QEvent(12345))
Which is understandable since the event is passed directly to receiving object.
C++
Similar example in C++:
foobar.h
#ifndef FOOBAR_H
#define FOOBAR_H
#include <QtGui>
class Foo : public QWidget
{
Q_OBJECT
public:
Foo(QWidget *parent = 0);
void doEvent();
bool event(QEvent *);
};
class Bar : public QWidget
{
Q_OBJECT
public:
Bar(QWidget *parent = 0);
Foo *foo;
bool event(QEvent *);
};
#endif // FOOBAR_H
foobar.cpp
#include "foobar.h"
Foo::Foo(QWidget *parent)
: QWidget(parent) {}
void Foo::doEvent() {
QEvent *event = new QEvent(QEvent::User);
QApplication::postEvent(this, event);
}
bool Foo::event(QEvent *event)
{
event->ignore();
return QWidget::event(event);
}
Bar::Bar(QWidget *parent)
: QWidget(parent)
{
foo = new Foo(this);
}
bool Bar::event(QEvent *event)
{
if (event->type() == QEvent::User) {
qDebug() << "Handler triggered";
return true;
}
return QWidget::event(event);
}
main.cpp
#include <QtGui>
#include "foobar.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Bar bar(0);
bar.show();
bar.foo->doEvent();
return app.exec();
}
Same as in python this only works if event is passed directly to an object.
void Foo::doEvent() {
QEvent *event = new QEvent(QEvent::User);
QApplication::postEvent(this->parentWidget(), event);
}
Perhaps I missed the point, is it possible that only Key and Mouse events are propagated upwards?