Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] QWidget - WA_TransparentForMouseEvents but not for children
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] QWidget - WA_TransparentForMouseEvents but not for children

Scheduled Pinned Locked Moved General and Desktop
6 Posts 2 Posters 8.6k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    maximus
    wrote on last edited by maximus
    #1

    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


    Free Indoor Cycling Software - https://maximumtrainer.com

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

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

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      M 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

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

        M Offline
        M Offline
        maximus
        wrote on last edited by
        #3

        @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.


        Free Indoor Cycling Software - https://maximumtrainer.com

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          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

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • M Offline
            M Offline
            maximus
            wrote on last edited by maximus
            #5

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

            Free Indoor Cycling Software - https://maximumtrainer.com

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Thanks for sharing !

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved