Кулак, извиняюсь за длину вопроса.
Я пытаюсь распространить пользовательское событие Qt от дочерних виджетов до верхнего родительского виджета, чтобы вызвать какое-то действие, основанное на типе события, вместо связывания сигналов.
Qt docs предполагает, что каждое событие, опубликованное с postEvent()
, имеющим методы accept()
и ignore()
, может распространяться (имеется в виду каждый QEvent
подкласс).
Я пытался переопределитьcustomEvents
метод вместо events
, но безрезультатно.
Python
Я пробовал это в Python, используя PyQt4 (версия Qt 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_()
В этом примере Bar.someEventHandler()
будет срабатывать только в том случае, если событие было опубликовано с self.parent()
в качестве первого аргумента, например так:
def doEvent(self):
QApplication.postEvent(self.parent(), QEvent(12345))
Это понятно, поскольку событие передается непосредственно получающему объекту.
C ++
Аналогичный пример в 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();
}
Так же, как в python, это работает только яСобытие f передается непосредственно объекту.
void Foo::doEvent() {
QEvent *event = new QEvent(QEvent::User);
QApplication::postEvent(this->parentWidget(), event);
}
Возможно, я упустил момент, возможно ли, что только события Key и Mouse распространяются вверх?