如何将点击事件传递到Qt下面的兄弟姐妹?

时间:2011-04-06 09:02:07

标签: qt qt4

我在窗口子A和子B中有两个重叠的小部件。孩子A在B之上并且获得鼠标事件但有时点击应该通过并最终命中孩子B.

理想的解决方案是使用event->ignore(),但这会将事件传递给父窗口小部件,而不是兄弟。

“全部通过”解决方案setAttribute(Qt::WA_TransparentForMouseEvents);也不起作用,因为子A需要捕获一些事件。

我怎么告诉Qt“我不想处理这个事件,表现得像我不在那里”?

4 个答案:

答案 0 :(得分:3)

更简单的解决方案(如果适用)是根据您的点击条件设置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的一年后写下来的,所以请在名称或类型错误上纠正我。

答案 1 :(得分:1)

如果Child-A必须忽略该事件,发出一个信号并用其父项捕获它,那么父项将发出一个新的信号,由Child-B捕获

Child-A - >家长 - >儿童-B
(信号) - > (槽)(信号) - > (插槽)

答案 2 :(得分:1)

您也可以从另一方面解决问题。您可以让其他窗口小部件使用事件过滤器监听第一个窗口小部件的事件,而不是将事件转发到“其他”窗口小部件。我不确定这是否适合您的用例,这取决于什么/谁决定哪些事件由哪个对象处理。

答案 3 :(得分:0)

这是一个可能的选择:

  1. 给孩子B指向孩子A objet。
  2. 重新定义bool QObjet :: event(QEvent * event),以便在需要时将事件重新发送给孩子B.
  3. 例如:

    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;
    
     }
    

    希望这有帮助。