Search code examples
qtqt5qwidgetqeventqmouseevent

Ignore and propagate QWidget click events to the OS


I have a top-level parentless QWidget on top of which I have a bunch of other QWidgets(e.g. QPushButtons). I would like to make my QWidget act like it is transparent for mouse events. So when I click on the QWidget(but not on my buttons) I want my window to lose focus and something in the back to be selected(e.g. a Windows Explorer window if it happens to be in the back of my window). I also want my QPushButtons to continue processing mouse events.

Is this possible? I tried setting the Qt::WA_TranslucentBackground and Qt::WA_TransparentForMouseEvents on the widget but if I draw something on it, e.g. a QGraphicsDropShadowEffect the widget still processes mouse click events on the parts where QGraphicsDropShadowEffect draws on it.

Is this possible?

Regards!


Solution

  • I found some solution. In my case this - is the pointer to QMainWindow. Main idea: catch click, get globalPos, hide window and give click to OS. But it should be OS specific code, I can give you example which works on Windows. You should create eventFilter (I hope you know how to do this, so I post next code).

    bool MainWindow::eventFilter(QObject *obj, QEvent *event)
    {
        if(obj == this && event->type() == QEvent::MouseButtonRelease)
        {
            qDebug() << "mouse";
            QMouseEvent *mouse = static_cast<QMouseEvent*>(event);
            qDebug() << mouse->globalPos();
            QPoint point = mouse->globalPos();
            this->hide();
            //start of OS specific code
            mouse_event(MOUSEEVENTF_LEFTDOWN,point.x(),point.y(),0,0);
            mouse_event(MOUSEEVENTF_LEFTUP,point.x(),point.y(),0,0);
            mouse_event(MOUSEEVENTF_LEFTDOWN,point.x(),point.y(),0,0);
            mouse_event(MOUSEEVENTF_LEFTUP,point.x(),point.y(),0,0);
            //this->show();//as you want
        }
    
    return QObject::eventFilter(obj, event);
    }
    

    In my example, window will hide and we emulate doubleclick. On my computer I can ignore QMainWindow and open picture which was closed by QMainWindow(I couldn't saw it, I saw only my QMainWindow, but click was ignored and we gave this click to OS)