Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

mouse press event on everything?



  • When a QPushButton in my program is pressed a QFrame that I've styled pops up. I want to remove that QFrame when I press anywhere, literally anywhere. Whether it is inside the program or outside, if it is on the QFrame or not, on a QTextEdit or a random QPushButton I still want the QFrame to disapear. I've got this

    void MainWindow::mousePressEvent(QMouseEvent *e) {
        Q_UNUSED(e);
    
        if(qframe_visible) {
            colored_qframe->hide();
            qframe_visible = false;
        }
    }
    

    but when I press inside a QTextEdit or on a QPushButton, the frame is still there! I know it works since when I press on another QFrame it disappears. I would like to avoid eventFilter, if possible.


  • Lifetime Qt Champion

    Hi
    You can write a widget class that will overlay the whole of main window
    and overrides its mousePressed. The widget is transparent so it's not visible.
    Then if clicked, you close it. The frame can just be placed in center of this widget or how you want it.

    It's not possible to detect mouse press outside your application. (with Qt)
    However, for the overlay widget, you can override leaveEvent and then
    close it/QFrame if it leaves the window.

    You might also be able to use grapMouse()
    https://doc.qt.io/qt-5/qwidget.html#grabMouse
    to simple get all mouse presses. But note the OS issues/features.



  • I tried

    void MainWindow::mousePressEvent(QMouseEvent *e) {
        Q_UNUSED(e);
    
        if(qframe_visible) {
            colored_qframe->hide();
            qframe_visible = false;
            overlay_widget->hide();
        }
    }
    

    which worked since wherever I press there is a transparent QWidget, but that creates a new issue. If I press inside a QTextEdit at this point then the QTextEdit doesn't get selected since there is an overlaying widget in the way. Therefore I need to press twice in order to select the QTextEdit (I hide the widget whilst also hiding the QFrame), which is not what I want. Is there another way? I don't really want to simulate a mouse click at the current mouse position when I press, as to simulate me pressing twice in order to select the QTextEdit or press a button, etc.


  • Lifetime Qt Champion

    @legitnameyo
    I dont know other ways. event filter can allow pass through so it don't suffer nearly the same but
    since you consume the click to close the Frame, then most solutions will suffer this.
    Why not just tone the overlay widget with some transparent color its clear to user that Frame is in foreground.
    Then he click to remove and then click on what he wants.

    You could also try making with changing focus. When you pop Frame, you set focus to it.
    if something else gets focus then close it.
    https://doc.qt.io/qt-5/qapplication.html#focusWidget
    But that only works if user clicks on something that can have focus.

    so if you dont want to use
    https://doc.qt.io/qt-5/qapplication.html#widgetAt
    and select it for focus after first close click then im afraid im
    out of ideas.


Log in to reply