如何将点击事件传递给Qt下的兄弟?
我在一个窗口子A和子B中有两个重叠的小部件。子A在B之上并且获取鼠标事件,但有时点击应该通过并最终碰到子B。如何将点击事件传递给Qt下的兄弟?
理想的解决方案是使用event->ignore()
但这会将事件传递给父窗口小部件,而不是兄弟。
“全部通过”解决方案setAttribute(Qt::WA_TransparentForMouseEvents);
不起作用,因为孩子A需要捕获一些事件。
我该如何告诉Qt“我不想处理这个事件,就像我不在那里一样?”?
如果事件已经由儿童-A被忽略,发射的信号,并且与它的父捕获它,则该父发射至由儿童-B
儿童-A被捕获新的信号 - >父(信号) - >(插槽)
更容易的解决方案(如果适用)是根据您的点击条件设置WA_TransparentForMouseEvents
。
例如,如果要单击Child-A的某些区域,则可以使用它的mouseMoveEvent()
来检查WA_TransparentForMouseEvents
是否需要设置或取消设置。然后点击事件自动通过。
如果你不能确定一个点击事件是否应该被接受的话,其实是被触发之前,你可以做这样的事情:
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);
}
免责声明:一年所有这一切都通过心脏写下来后一不做Qt,所以请纠正我的名称或类型错误。
我知道这是旧的,但只是你知道,一旦我激活它,我不能将它设置为假。 – Romain 2014-08-05 08:18:27
这里是一个可能的选择:
- 给小孩B指向孩子客体。
- 重新定义布尔QObjet :: event(QEvent *事件)以在需要时将事件重新转发给子B。
例如:
bool WidgetA::event(QEvent *event)
{
QWidget::event(event);
QEvent::Type type = event->type();
if ((type != QEvent::KeyPress) &&
(type != QEvent::Wheel) &&
(type != QEvent::MouseButtonDblClick) &&
(type != QEvent::MouseMove) &&
(type != QEvent::MouseButtonPress))
return true;
//forward the event
if (m_pChildB)
m_pChildB->event(event);
return true;
}
希望这有助于。
您也可以从另一端处理问题。您可以让其他小部件使用事件过滤器监听第一个小部件的事件,而不是将事件转发到“其他”小部件。我不确定这是否适合您的用例,这取决于什么/谁决定哪些事件将由什么对象来处理。
您可以设置“全部通过”选项并从鼠标事件处理程序重新发送鼠标事件吗?事件结束后,再次设置为false。可能导致无限递归..也许你应该在主窗口中为子A安装一个事件过滤器,试着如果A管理事件,如果不是,检查它是否在子B的区域,如果是,将它传递给它?这应该起作用,但可能有点破解。否则,我会看到A应该知道B并能够将事件传递给它的可能性。 – 0xbaadf00d 2011-04-06 09:16:09
通过查看Qt的源代码,'QWidgetPrivate :: childAtRecursiveHelper'找到一个匹配的子项(用'WA_TransparentForMouseEvents'过滤这些子项,然后调用子项的事件处理程序,但是这个调用发生在子查找方法之外,所以唯一的解决方案似乎是管理点击从父母那里手工操作... – gaspard 2011-04-06 09:34:36