Hi Wysota,
Thanks a lot for your help. Sorry for the late response but I was very busy.
Are you sure you want to do it with widgets? Using QGraphicsView and its items instead would be much simpler for you. And you'd get the event behaviour you want for free.
At the beginning of the project I have evaluated QGraphicsView vs QWidget... That was a difficult choice to do... I think that there was more work if I done it with the GraphicsView and my knowledge of QWidget was for more superior. Given the time available to complete the component, I chose to go with the QWidget. Now it's too late to go back...
The code is probably in QCoreApplication::notify(). You can reimplement it if you want, but I really wouldn't do that here. What you could do is to bounce back those events in the "parent" as it is the one that knows where each widget is. But I'd suggest switching to Graphics View, it should really be helpful here and possibly in future as well.
That's what's save my day! Now I use the QCoreApplication::notify() to notify all child. This method translates the event in the context of the child. The only case where I need to do a manual translation is for the position the mouse event (mapFromGlobal..)
QList<QWidget*> childListCopy = m_childList;
bool notified = false;
QEvent::Type t
= event
->type
();
while (!childListCopy.isEmpty())
{
QWidget* childWidget
= childListCopy.
takeLast();
if(t
== QEvent::MouseButtonPress ||
t
== QEvent::MouseButtonDblClick ||
t
== QEvent::MouseButtonRelease ||
)
{
childWidget->mapFromGlobal(me->globalPos()),
me->globalPos(),
me->button(),
me->buttons(),
me->modifiers());
if(qApp->notify(childWidget,&mouseEvent))
{
notified = true;
}
}
else
{
{
if(qApp->notify(childWidget,event))
{
notified = true;
}
}
}
}
if(notified)
{
return true;
}
else
{
return QObject::eventFilter(obj, event
);
}
}
bool TrackElement::eventFilter(QObject *obj, QEvent *event)
QList<QWidget*> childListCopy = m_childList;
bool notified = false;
QEvent::Type t = event->type();
while (!childListCopy.isEmpty())
{
QWidget* childWidget = childListCopy.takeLast();
if(t == QEvent::MouseButtonPress ||
t == QEvent::MouseButtonDblClick ||
t == QEvent::MouseButtonRelease ||
t == QEvent::MouseMove
)
{
QMouseEvent* me = static_cast<QMouseEvent*>(event);
QMouseEvent mouseEvent(me->type(),
childWidget->mapFromGlobal(me->globalPos()),
me->globalPos(),
me->button(),
me->buttons(),
me->modifiers());
if(qApp->notify(childWidget,&mouseEvent))
{
notified = true;
}
}
else
{
if(t != QEvent::Wheel)
{
if(qApp->notify(childWidget,event))
{
notified = true;
}
}
}
}
if(notified)
{
return true;
}
else
{
return QObject::eventFilter(obj, event);
}
}
To copy to clipboard, switch view to plain text mode
I know, it's an ugly hack with ugly sides effects... For instance: I can't prevent the forwarding of event from child widget to his parent. Since I iterate in a list of childWidget and then sends events to each of them, the parent will be notified more than one time with the same event... This is a problem is my case for the QEvent::Wheel...
In the next refact of this component, I will try to go with the QGraphicsView. It's unfortunate but sometimes you need to make it works in the wrong way in order to understand how to make it works in the good way. One step closer to the Qt::Guru state!
Thanks again for your help, very appreciated...
planglois
Bookmarks