Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make a QWidget semitransparent to events?

Tags:

qt

I've seen similar questions but no answers that fit what I need. I want an invisible widget that lives on top of my whole application (no problems here). I want this widget to catch events so that I can print stuff about them, record them, whatever. I currently have an event filter hooked up that does this just fine. Then I want it to let the event go through to whatever is behind the widget. So for instance, if I try to push a button, the invisible widget should notice that a press happened on that spot, and then the button should actually be pressed. Can this be done in a simple way, or am I going to have to write code to simulate all the events beneath the invisible widget?

like image 957
Brianide Avatar asked Oct 04 '22 08:10

Brianide


1 Answers

From all the information you disclosed in the comments, I suggest you filter the event as previously discussed, and then use QCoreApplication::sendEvent to forward the desired events to the invisible widget. It will then propagate the event accordingly to its children.

EDIT: OK, here is quick example that includes a QObject based event filter, that will filter the events for a widget, if the event is mouse event, it will be left for the widget to handle and print the output, if the event is a key event, it will be filtered and not forwarded back to the widget:

The event filter class:

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

The widget:

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

Testing output to show that keyboard events are filtered and mouse press events are forwarded to the widget:

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
like image 188
dtech Avatar answered Oct 13 '22 12:10

dtech