如何使QWidget对事件半透明?

5

我看到了类似的问题,但没有符合我的需求的答案。我想要一个不可见的小部件,可以覆盖在我的整个应用程序上面(这没问题)。我希望这个小部件可以捕获事件,以便我可以打印相关信息、记录它们或进行其他操作。我目前已经连接了一个事件过滤器,在这方面做得很好。然后,我希望它能让事件通过并传递给小部件后面的任何东西。例如,如果我尝试按下一个按钮,不可见的小部件应该注意到在那个位置发生了按下事件,然后按钮应该实际被按下。这是否可以简单地完成,或者我需要编写代码来模拟不可见小部件下面的所有事件?


为什么不安装事件过滤器? - dtech
1
为什么不直接处理事件,然后发出连接到你的不可见小部件的信号? - dtech
eventFilter()返回true - 这告诉事件循环将事件进一步转发。否则,该事件将被消耗。 - dtech
不行。QObject::eventfilter() 的 Qt API 表示:“在您重新实现此函数时,如果要过滤事件,即停止进一步处理它,请返回 true;否则返回 false。”然而,我也尝试了返回 false,但无济于事。无论如何,它似乎都会吞噬事件。 - Brianide
啊,是的,如果事件被过滤了就返回“true”。至于为什么这对你不起作用——你的小部件可能需要处于活动焦点才能接收事件。 - dtech
显示剩余4条评论
1个回答

4

根据您在评论中提供的所有信息,我建议您按照先前讨论的方式过滤事件,然后使用QCoreApplication :: sendEvent将所需事件转发给不可见小部件。 然后它会相应地传播事件给其子级。

编辑:好的,这里是一个快速示例,包括基于QObject的事件过滤器,如果事件是鼠标事件,则留给小部件处理并输出,如果事件是键盘事件,则进行过滤并不会返回到小部件:

事件过滤器类:

    class EventInfo : public QObject {
    Q_OBJECT
public:
    explicit EventInfo(QObject *parent = 0) : QObject(parent) {}

    bool eventFilter(QObject *, QEvent *e) {
        if (e->type() == QEvent::MouseButtonRelease){
            qDebug() << "click event not filtered";
            return false;
        }
        if (e->type() == QEvent::KeyRelease) {
            QKeyEvent *event = static_cast<QKeyEvent *>(e);
            if (event) qDebug() << "key" << event->key() << "filtered";
            return true;
        }
        return false;
    }
};

小部件:
class Widget : public QWidget {
    Q_OBJECT

public:
    Widget(QWidget *parent = 0) : QWidget(parent) {}

protected:
    void mouseReleaseEvent(QMouseEvent *e) {
        qDebug() << "widget clicked at position" << e->pos();
    }

    void keyReleaseEvent(QKeyEvent *e) {
        qDebug() << "pressed key" << e->key();
    }
};

main.cpp:

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    Widget w;
    EventInfo info;
    w.installEventFilter(&info);
    w.show();    
    return a.exec();
}

测试输出以显示键盘事件被过滤,鼠标按下事件被转发到小部件:

click event not filtered
widget clicked at position QPoint(352,230) 

key 70 filtered 

click event not filtered
widget clicked at position QPoint(405,163) 

key 87 filtered

不可见的小部件是首先捕获事件的小部件。我需要将事件转发到可见小部件的后面。但是,可能有一个适当的父级可以将它们转发到。我会进行调查! - Brianide
您可以将任何小部件转发,它不必是当前父子层次结构的一部分。 - dtech
我现在正在尝试通过隐藏不可见的小部件,然后将事件转发到与事件相同位置的小部件,然后再次显示不可见的小部件来欺骗它。 - Brianide
呃,也许只是我,但是你怎么“展示”看不见的呢 :) - dtech
1
@Brianide 我更新了我的答案,并提供了一个示例。 过滤器不是一个不可见的小部件,但你会明白的。 - dtech
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接