[SOLVED] QWidget - WA_TransparentForMouseEvents but not for children



  • I have a QWidget that is on top of a QwtPlot.

    I made the QWidget transparent for mouse events so that the plot can receive the mouseMoved event underneath.
    The problem is this:
    I also have a child QWidget inside this parent widget that would like to receive mouseEvent. but since the parent has the flag on, the child cannot receive any mouse event.

    Example in action :
    https://www.dropbox.com/s/t8ao6asilr8gt75/mouseEventProblem.png?dl=0
    (QSpinBox can't receive anymore focus and be edited since the parent QWidget has the attribute "WA_TransparentForMouseEvents ")

    Here is my code for reference, I tried bunch of things for 1-2hrs (eventFilter, etc.) but seems like it's not possible to have child receive any mouse event if the parent is transparentForMouseEvent

        QWidget *widgetMsg = new QWidget(this);
        QVBoxLayout *vlayout = new QVBoxLayout(this);
        vlayout->setMargin(0);
        vlayout->setSpacing(0);
    
        QSpacerItem *spacer = new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
    
        labelMsgInterval = new FaderLabel(this);
        labelMsgInterval->setStyleSheet("background-color : rgba(1,1,1,140);"
                                        "border-radius: 15px;"
                                        "border: 1px solid beige;");
        labelMsgInterval->setMinimumHeight(60);
        labelMsgInterval->setMaximumHeight(90);
        labelMsgInterval->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
        labelMsgInterval->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        labelMsgInterval->hide();
    
        QWidget *widgetTopForSpinBox = new QWidget(this);
        QHBoxLayout *hlayout = new QHBoxLayout(this);
        hlayout->setMargin(0);
        hlayout->setSpacing(0);
        hlayout->setContentsMargins(0,0,0,0);
        QSpinBox *spinBoxDifficulty = new QSpinBox(this);
        spinBoxDifficulty->setButtonSymbols(QAbstractSpinBox::PlusMinus);
        spinBoxDifficulty->setMinimum(-100);
        spinBoxDifficulty->setMaximum(100);
        spinBoxDifficulty->setSuffix("%"); //±%
        spinBoxDifficulty->setFixedHeight(30);
        spinBoxDifficulty->setFixedWidth(55);
        spinBoxDifficulty->setValue(0);
        spinBoxDifficulty->setStyleSheet("background-color : rgb(35,35,35); color : white;");
        spinBoxDifficulty->setKeyboardTracking(false);
    
        connect(spinBoxDifficulty, SIGNAL(valueChanged(int)), this, SIGNAL(workoutDifficultyChanged(int)));
    
        hlayout->setAlignment(Qt::AlignRight | Qt::AlignTop);
        hlayout->addWidget(spinBoxDifficulty);
        widgetTopForSpinBox->setLayout(hlayout);
    
        vlayout->addWidget(widgetTopForSpinBox);
        vlayout->addSpacerItem(spacer);
        vlayout->addWidget(labelMsgInterval, Qt::AlignBottom);
    
        QFont fontBig;
        fontBig.setPointSize(20);
        labelMsg->setFont(fontBig);
        labelMsgInterval->setFont(fontBig);
    
        widgetMsg->setLayout(vlayout);
        //------------------------------
    
        widgetCanvas = this->canvas();
        QGridLayout *gridLayout = new QGridLayout(this);
        gridLayout->setMargin(0);
        gridLayout->setSpacing(0);
        gridLayout->setContentsMargins(0,0,0,0);
        gridLayout->addWidget(labelMsg, 0, 0, 1, 1);
    
        gridLayout->addWidget(widgetMsg, 0, 0, 1, 1);
        widgetCanvas->setLayout(gridLayout);
    
        widgetMsg->installEventFilter(this); //tried this option, no success..
    
        //        widgetTopForSpinBox->setAttribute(Qt::WA_TransparentForMouseEvents, false);
        //        spinBoxDifficulty->setAttribute(Qt::WA_TransparentForMouseEvents, false);
        widgetMsg->setAttribute(Qt::WA_TransparentForMouseEvents, true);
        labelMsg->setAttribute(Qt::WA_TransparentForMouseEvents, true);
        labelMsgInterval->setAttribute(Qt::WA_TransparentForMouseEvents, true);
    

    Other thread with no clear solution :
    http://stackoverflow.com/questions/5563862/how-to-pass-click-event-to-sibling-underneath-in-qt


  • Lifetime Qt Champion

    Hi,

    How should that widget work ? Is it always there ? Should it appear at some point ?



  • @SGaist

    The QWidget on top of the Qwtplot is always there and contains QLabel that are invisible and set to Visible when I need to display a message on top of the QwtPlot. The QSpinBox is always there and always visible.


  • Lifetime Qt Champion

    In that case, why not make it independent of your other widget ? Move it at the right position on top of that "information widget" so you don't need to fiddle with event transparency for it



  • Thanks SGaist! Finally got it to work, I add to rethink the whole layout .
    Now I have a QwtPlotPicker with custom text shown when my cursor is on the graph (x,y), and a normal cursor when I'm on the SpinBox. Had to do an event filter because the text would not clear on the cursor when going on the QSpinBox.

    Sharing the code in case it helps someone.

        QWidget *widgetMsg = new QWidget(this);
        QVBoxLayout *vlayout = new QVBoxLayout(this);
        vlayout->setMargin(0);
        vlayout->setSpacing(0);
        vlayout->setAlignment(Qt::AlignBottom);
    
    
        labelMsgInterval = new FaderLabel(this);
        labelMsgInterval->setStyleSheet("background-color : rgba(1,1,1,140);"
                                        "border-radius: 15px;"
                                        "border: 1px solid beige;");
        labelMsgInterval->setMinimumHeight(60);
        labelMsgInterval->setMaximumHeight(90);
        labelMsgInterval->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
        labelMsgInterval->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        labelMsgInterval->hide();
        vlayout->addWidget(labelMsgInterval);
    
        QSpinBox *spinBoxDifficulty = new QSpinBox(this);
        spinBoxDifficulty->setButtonSymbols(QAbstractSpinBox::PlusMinus);
        spinBoxDifficulty->setMinimum(-100);
        spinBoxDifficulty->setMaximum(100);
        spinBoxDifficulty->setSuffix("%"); //±%
        spinBoxDifficulty->setFixedHeight(30);
        spinBoxDifficulty->setFixedWidth(55);
        spinBoxDifficulty->setValue(0);
        spinBoxDifficulty->setStyleSheet("background-color : rgb(35,35,35); color : white;");
        spinBoxDifficulty->setKeyboardTracking(false);
        spinBoxDifficulty->setCursor(Qt::ArrowCursor);
        connect(spinBoxDifficulty, SIGNAL(valueChanged(int)), this, SIGNAL(workoutDifficultyChanged(int)));
    
        QFont fontBig;
        fontBig.setPointSize(20);
        labelMsg->setFont(fontBig);
        labelMsgInterval->setFont(fontBig);
        widgetMsg->setLayout(vlayout);
        //------------------------------
        widgetCanvas = this->canvas();
        QGridLayout *gridLayout = new QGridLayout(this);
        gridLayout->setMargin(0);
        gridLayout->setSpacing(0);
        gridLayout->setContentsMargins(0,0,0,0);
        gridLayout->addWidget(spinBoxDifficulty, 0, 1, 1, 1);
        gridLayout->addWidget(labelMsg, 0, 0, 2, 2);
        gridLayout->addWidget(widgetMsg, 0, 0, 2, 2);
        widgetCanvas->setLayout(gridLayout);
    
        spinBoxDifficulty->installEventFilter(this);
    
        widgetMsg->setAttribute(Qt::WA_TransparentForMouseEvents, true);
        labelMsg->setAttribute(Qt::WA_TransparentForMouseEvents, true);
        labelMsgInterval->setAttribute(Qt::WA_TransparentForMouseEvents, true);
    

    Event filter

        bool WorkoutPlot::eventFilter(QObject *watched, QEvent *event) {
        
        
            QSpinBox *ptrSpinBox = qobject_cast<QSpinBox*>(watched);
        
            if (ptrSpinBox != NULL) {
                if (event->type() == QEvent::HoverEnter) {
                    d_picker->setEnabled(false);
                }
                else if (event->type() == QEvent::HoverLeave) {
                    d_picker->setEnabled(true);
                }
            }
            return false;
        }

  • Lifetime Qt Champion

    Thanks for sharing !


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.