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. How to receive mouse events for QDoubleSpinBox
Forum Updated to NodeBB v4.3 + New Features

How to receive mouse events for QDoubleSpinBox

Scheduled Pinned Locked Moved Solved General and Desktop
23 Posts 8 Posters 3.4k 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.
  • S Offline
    S Offline
    summit
    wrote on last edited by summit
    #1

    I want to receive the mouse click event in the subClass of QDoubleSpinBox

    This is my code but in the function void SumDoubleBox::mousePressEvent(QMouseEvent* event) does not get invoked when i click on the spinbox.

    class SumDoubleBox : public QDoubleSpinBox
    {
    	Q_OBJECT
    public:
    	using QDoubleSpinBox::QDoubleSpinBox;  // inherit c'tors
    	// re-implement to keep track of default step (optional, could hard-code step in stepBy())
    	void setSingleStep(double val);
    	// override to adjust step size
    	void stepBy(int steps) override;
    protected:
    	void mousePressEvent(QMouseEvent* event);
    		
    public slots:	
    	void setZero();
    
    
    private:
    	double m_defaultStep = 1.0;
    };
    

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    #include <SumDoubleBox.h>
     #include <qlineedit.h>
     #include <qdebug.h>
    
     void SumDoubleBox::setSingleStep(double val)
     {
       m_defaultStep = val;
       QDoubleSpinBox::setSingleStep(val);
     }
    // override to adjust step size
     void SumDoubleBox::stepBy(int steps)
       {
    // set the actual step size here
    double newStep = m_defaultStep;
    if (QApplication::queryKeyboardModifiers() & Qt::ShiftModifier)
    	newStep *= 0.1;
    // be sure to call the base setSingleStep() here, otherwise redundant loop.
    QDoubleSpinBox::setSingleStep(newStep);
    QDoubleSpinBox::stepBy(steps);
    }
    
    void SumDoubleBox::setZero()
    {
    QDoubleSpinBox::setValue(0.0);	
    }
    
     void SumDoubleBox::mousePressEvent(QMouseEvent* event)
     {
         qDebug() << "Mouse pressed";
    }
    
    Pl45m4P 1 Reply Last reply
    0
    • S summit

      I want to receive the mouse click event in the subClass of QDoubleSpinBox

      This is my code but in the function void SumDoubleBox::mousePressEvent(QMouseEvent* event) does not get invoked when i click on the spinbox.

      class SumDoubleBox : public QDoubleSpinBox
      {
      	Q_OBJECT
      public:
      	using QDoubleSpinBox::QDoubleSpinBox;  // inherit c'tors
      	// re-implement to keep track of default step (optional, could hard-code step in stepBy())
      	void setSingleStep(double val);
      	// override to adjust step size
      	void stepBy(int steps) override;
      protected:
      	void mousePressEvent(QMouseEvent* event);
      		
      public slots:	
      	void setZero();
      
      
      private:
      	double m_defaultStep = 1.0;
      };
      

      //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

      #include <SumDoubleBox.h>
       #include <qlineedit.h>
       #include <qdebug.h>
      
       void SumDoubleBox::setSingleStep(double val)
       {
         m_defaultStep = val;
         QDoubleSpinBox::setSingleStep(val);
       }
      // override to adjust step size
       void SumDoubleBox::stepBy(int steps)
         {
      // set the actual step size here
      double newStep = m_defaultStep;
      if (QApplication::queryKeyboardModifiers() & Qt::ShiftModifier)
      	newStep *= 0.1;
      // be sure to call the base setSingleStep() here, otherwise redundant loop.
      QDoubleSpinBox::setSingleStep(newStep);
      QDoubleSpinBox::stepBy(steps);
      }
      
      void SumDoubleBox::setZero()
      {
      QDoubleSpinBox::setValue(0.0);	
      }
      
       void SumDoubleBox::mousePressEvent(QMouseEvent* event)
       {
           qDebug() << "Mouse pressed";
      }
      
      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by Pl45m4
      #2

      @summit said in How to receive mouse events for QDoubleSpinBox:

      does not get invoked when i click on the spinbox.

      It does... But only if you click the spinBox Widget, not the lineEdit or something else.
      If you click the up and down buttons, it should print Mouse pressed (your code worked for me, at least).

      Add override to your function definition and dont forget to pass the event to the base class after you did your stuff (unless you want to interrupt that)

      void SumDoubleBox::mousePressEvent(QMouseEvent* event)
      {
           qDebug() << "Mouse pressed";
           QDoubleSpinBox::mousePressEvent(event);
      }
      
      

      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      1 Reply Last reply
      2
      • S Offline
        S Offline
        summit
        wrote on last edited by
        #3

        @Pl45m4 Thank you for reply , i am able to see the Mouse pressed printed when i click on the up and down arrows but i want to invoke the mouse press event in the lineEdit .

        mrjjM 1 Reply Last reply
        0
        • S summit

          @Pl45m4 Thank you for reply , i am able to see the Mouse pressed printed when i click on the up and down arrows but i want to invoke the mouse press event in the lineEdit .

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @summit
          Hi
          you can either set your own LineEdit with mouse press override to the
          spinBox.
          https://doc.qt.io/qt-5/qabstractspinbox.html#setLineEdit

          or use event filter on the LineEdit to catch the click.
          https://forum.qt.io/topic/67705/capture-mouse-click-on-qlineedit

          1 Reply Last reply
          3
          • S Offline
            S Offline
            summit
            wrote on last edited by
            #5

            @mrjj Thank you , i am able to use event filter but bit confused on how to use setLineEdit.
            Can you please guide me towards some tutorial or show some sample code.

            jsulmJ 1 Reply Last reply
            0
            • S summit

              @mrjj Thank you , i am able to use event filter but bit confused on how to use setLineEdit.
              Can you please guide me towards some tutorial or show some sample code.

              jsulmJ Online
              jsulmJ Online
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @summit said in How to receive mouse events for QDoubleSpinBox:

              Can you please guide me towards some tutorial

              Why do you need a tutorial for that?
              Create a QLineEdit instance and pass its pointer to setLineEdit()...

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              4
              • S Offline
                S Offline
                shreya_agrawal
                wrote on last edited by
                #7

                Hello!
                Is there any way to get get the click events of the up and down buttons separately in the spin box?

                Pl45m4P 1 Reply Last reply
                0
                • dheerendraD Offline
                  dheerendraD Offline
                  dheerendra
                  Qt Champions 2022
                  wrote on last edited by
                  #8

                  @shreya_agrawal - No direct way without overriding appropriate mouseEvent methods. As work-around you can check the change in value. You can decide up or down based on value increment/decrement.

                  Dheerendra
                  @Community Service
                  Certified Qt Specialist
                  http://www.pthinks.com

                  S 1 Reply Last reply
                  0
                  • S shreya_agrawal

                    Hello!
                    Is there any way to get get the click events of the up and down buttons separately in the spin box?

                    Pl45m4P Offline
                    Pl45m4P Offline
                    Pl45m4
                    wrote on last edited by
                    #9

                    @shreya_agrawal

                    You could use the valueChanged signal and check if the new value is higher or lower than the old one. Then you know what button what possibly clicked... (or what value was added via typing, if you can live with that)


                    If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                    ~E. W. Dijkstra

                    1 Reply Last reply
                    0
                    • dheerendraD dheerendra

                      @shreya_agrawal - No direct way without overriding appropriate mouseEvent methods. As work-around you can check the change in value. You can decide up or down based on value increment/decrement.

                      S Offline
                      S Offline
                      shreya_agrawal
                      wrote on last edited by
                      #10

                      @dheerendra
                      Thank you for your reply !
                      Are you aware of any mouse events which can be used for this, so I don't have to use the valueChanged signal?
                      I did find a workaround by using rectangles inside the spin box to distinguish between up and down buttons, but I don't think this is the most accurate approach.

                      JonBJ 1 Reply Last reply
                      0
                      • S shreya_agrawal

                        @dheerendra
                        Thank you for your reply !
                        Are you aware of any mouse events which can be used for this, so I don't have to use the valueChanged signal?
                        I did find a workaround by using rectangles inside the spin box to distinguish between up and down buttons, but I don't think this is the most accurate approach.

                        JonBJ Online
                        JonBJ Online
                        JonB
                        wrote on last edited by
                        #11

                        @shreya_agrawal
                        Have you investigated something based on:

                        for (QWidget *child: spinBox.findChildren<QWidget *>())
                            child->installEventFilter(this);
                        

                        I am not sure whether the buttons you want are widgets or (as may well be the case) simply drawn as part of the style. The above will at least show where actual widgets are.

                        S 1 Reply Last reply
                        0
                        • JonBJ JonB

                          @shreya_agrawal
                          Have you investigated something based on:

                          for (QWidget *child: spinBox.findChildren<QWidget *>())
                              child->installEventFilter(this);
                          

                          I am not sure whether the buttons you want are widgets or (as may well be the case) simply drawn as part of the style. The above will at least show where actual widgets are.

                          S Offline
                          S Offline
                          shreya_agrawal
                          wrote on last edited by
                          #12

                          @JonB
                          Thank you for your reply!
                          Actually the only child the spin box returns is its line edit, not the up and down buttons.

                          JonBJ 1 Reply Last reply
                          0
                          • S shreya_agrawal

                            @JonB
                            Thank you for your reply!
                            Actually the only child the spin box returns is its line edit, not the up and down buttons.

                            JonBJ Online
                            JonBJ Online
                            JonB
                            wrote on last edited by
                            #13

                            @shreya_agrawal
                            Yes, I think I read that. Sadly it means the arrows are just drawn as part of the style, they are not widgets you can connect to. Which should mean click is recognised by coordinates internally in spinbox code. Not what you wanted. You might examine Qt source code if you really need to know how it does it. It does sound as though working on valueChanged(), which the internal code must resolve via mouse position relative to arrow drawing, would be the simplest "high level" approach if you want to avoid duplicating internal coordinate calculation.

                            S 1 Reply Last reply
                            1
                            • JonBJ JonB

                              @shreya_agrawal
                              Yes, I think I read that. Sadly it means the arrows are just drawn as part of the style, they are not widgets you can connect to. Which should mean click is recognised by coordinates internally in spinbox code. Not what you wanted. You might examine Qt source code if you really need to know how it does it. It does sound as though working on valueChanged(), which the internal code must resolve via mouse position relative to arrow drawing, would be the simplest "high level" approach if you want to avoid duplicating internal coordinate calculation.

                              S Offline
                              S Offline
                              shreya_agrawal
                              wrote on last edited by
                              #14

                              @JonB
                              Okay, I will look into it further and post if I reach somewhere.

                              JonBJ 2 Replies Last reply
                              0
                              • Christian EhrlicherC Offline
                                Christian EhrlicherC Offline
                                Christian Ehrlicher
                                Lifetime Qt Champion
                                wrote on last edited by
                                #15

                                override mousePressEvent and get the positions of the spinboxes through the style with subElementRect() - this is what QAbstractSpinBox is doing

                                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                Visit the Qt Academy at https://academy.qt.io/catalog

                                JonBJ 1 Reply Last reply
                                4
                                • S shreya_agrawal

                                  @JonB
                                  Okay, I will look into it further and post if I reach somewhere.

                                  JonBJ Online
                                  JonBJ Online
                                  JonB
                                  wrote on last edited by
                                  #16

                                  @shreya_agrawal
                                  I've had a look at the on-line source (I don't have source files myself). Although I haven't gone all the way the through, the gist seems to be that Qt notes whether you mouse down on what it maintains as an internal "hover control", which will be the up arrow, down arrow or nothing.

                                  The relevant functions are https://codebrowser.dev/qt6/qtbase/src/widgets/widgets/qabstractspinbox.cpp.html#_ZN16QAbstractSpinBox15mousePressEventEP11QMouseEvent

                                  void QAbstractSpinBox::mousePressEvent(QMouseEvent *event)
                                  {
                                      Q_D(QAbstractSpinBox);
                                      d->keyboardModifiers = event->modifiers();
                                      if (event->button() != Qt::LeftButton || d->buttonState != None) {
                                          return;
                                      }
                                      d->updateHoverControl(event->position().toPoint());
                                      event->accept();
                                      const StepEnabled se = (d->buttonSymbols == NoButtons) ? StepEnabled(StepNone) : stepEnabled();
                                      if ((se & StepUpEnabled) && d->hoverControl == QStyle::SC_SpinBoxUp) {
                                          d->updateState(true);
                                      } else if ((se & StepDownEnabled) && d->hoverControl == QStyle::SC_SpinBoxDown) {
                                          d->updateState(false);
                                      } else {
                                          event->ignore();
                                      }
                                  }
                                  

                                  and the call to d->updateHoverControl(event->position().toPoint()); https://codebrowser.dev/qt6/qtbase/src/widgets/widgets/qabstractspinbox.cpp.html#_ZN23QAbstractSpinBoxPrivate18updateHoverControlERK6QPoint

                                  /*!
                                      \internal
                                      Updates the old and new hover control. Does nothing if the hover
                                      control has not changed.
                                  */
                                  bool QAbstractSpinBoxPrivate::updateHoverControl(const QPoint &pos)
                                  {
                                      Q_Q(QAbstractSpinBox);
                                      QRect lastHoverRect = hoverRect;
                                      QStyle::SubControl lastHoverControl = hoverControl;
                                      bool doesHover = q->testAttribute(Qt::WA_Hover);
                                      if (lastHoverControl != newHoverControl(pos) && doesHover) {
                                          q->update(lastHoverRect);
                                          q->update(hoverRect);
                                          return true;
                                      }
                                      return !doesHover;
                                  }
                                  /*!
                                      \internal
                                      Returns the hover control at \a pos.
                                      This will update the hoverRect and hoverControl.
                                  */
                                  QStyle::SubControl QAbstractSpinBoxPrivate::newHoverControl(const QPoint &pos)
                                  {
                                      Q_Q(QAbstractSpinBox);
                                      QStyleOptionSpinBox opt;
                                      q->initStyleOption(&opt);
                                      opt.subControls = QStyle::SC_All;
                                      hoverControl = q->style()->hitTestComplexControl(QStyle::CC_SpinBox, &opt, pos, q);
                                      hoverRect = q->style()->subControlRect(QStyle::CC_SpinBox, &opt, hoverControl, q);
                                      return hoverControl;
                                  }
                                  

                                  So ultimately I think it relies on

                                      hoverControl = q->style()->hitTestComplexControl(QStyle::CC_SpinBox, &opt, pos, q);
                                      hoverRect = q->style()->subControlRect(QStyle::CC_SpinBox, &opt, hoverControl, q);
                                  

                                  to find the location of the arrow buttons. And https://codebrowser.dev/qt6/qtbase/src/widgets/widgets/qabstractspinbox.cpp.html#_ZNK16QAbstractSpinBox15initStyleOptionEP19QStyleOptionSpinBox includes

                                      if (d->buttonSymbols != QAbstractSpinBox::NoButtons) {
                                          option->subControls |= QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown;
                                          if (d->buttonState & Up) {
                                              option->activeSubControls = QStyle::SC_SpinBoxUp;
                                          } else if (d->buttonState & Down) {
                                              option->activeSubControls = QStyle::SC_SpinBoxDown;
                                          }
                                  

                                  so this is to do with recognising which button ultimately.

                                  So like I said unless you want to replicate this (see QStyle for some of the calls) it would be easier for you to react to the generated valueChanged() signal.

                                  1 Reply Last reply
                                  3
                                  • Christian EhrlicherC Christian Ehrlicher

                                    override mousePressEvent and get the positions of the spinboxes through the style with subElementRect() - this is what QAbstractSpinBox is doing

                                    JonBJ Online
                                    JonBJ Online
                                    JonB
                                    wrote on last edited by
                                    #17

                                    @Christian-Ehrlicher said in How to receive mouse events for QDoubleSpinBox:

                                    override mousePressEvent and get the positions of the spinboxes through the style with subElementRect() - this is what QAbstractSpinBox is doing

                                    Ooohh, you posted this while I was doing all my source code searching! Not sure how your subElementRect() relates to the subControlRect() I have come across in the code above.

                                    1 Reply Last reply
                                    0
                                    • S shreya_agrawal

                                      @JonB
                                      Okay, I will look into it further and post if I reach somewhere.

                                      JonBJ Online
                                      JonBJ Online
                                      JonB
                                      wrote on last edited by
                                      #18

                                      @shreya_agrawal
                                      Ah ha! I little Googling leads me to QSpinbox Check if up or down button is pressed which seems to give the relatively simple code

                                      class SpinBox(QSpinBox):
                                          upClicked = pyqtSignal()
                                          downClicked = pyqtSignal()
                                      
                                          def mousePressEvent(self, event):
                                              super().mousePressEvent(event)
                                      
                                              opt = QStyleOptionSpinBox()
                                              self.initStyleOption(opt)
                                      
                                              control = self.style().hitTestComplexControl(
                                                  QStyle.CC_SpinBox, opt, event.pos(), self
                                              )
                                              if control == QStyle.SC_SpinBoxUp:
                                                  self.upClicked.emit()
                                              elif control == QStyle.SC_SpinBoxDown:
                                                  self.downClicked.emit()
                                      

                                      @eyllanesc's answers & code are usually good, so it may be this simple.

                                      S 1 Reply Last reply
                                      2
                                      • JonBJ JonB

                                        @shreya_agrawal
                                        Ah ha! I little Googling leads me to QSpinbox Check if up or down button is pressed which seems to give the relatively simple code

                                        class SpinBox(QSpinBox):
                                            upClicked = pyqtSignal()
                                            downClicked = pyqtSignal()
                                        
                                            def mousePressEvent(self, event):
                                                super().mousePressEvent(event)
                                        
                                                opt = QStyleOptionSpinBox()
                                                self.initStyleOption(opt)
                                        
                                                control = self.style().hitTestComplexControl(
                                                    QStyle.CC_SpinBox, opt, event.pos(), self
                                                )
                                                if control == QStyle.SC_SpinBoxUp:
                                                    self.upClicked.emit()
                                                elif control == QStyle.SC_SpinBoxDown:
                                                    self.downClicked.emit()
                                        

                                        @eyllanesc's answers & code are usually good, so it may be this simple.

                                        S Offline
                                        S Offline
                                        shreya_agrawal
                                        wrote on last edited by shreya_agrawal
                                        #19

                                        @JonB
                                        Well thank you for sparing so much of your time!
                                        Sadly, the Qt version I am using does not support the use of SC_SpinBoxUp and SC_SpinBoxDown subcontrols :(
                                        I think I will have to rely on the valueChanged() signal for now.

                                        JonBJ 1 Reply Last reply
                                        0
                                        • S shreya_agrawal

                                          @JonB
                                          Well thank you for sparing so much of your time!
                                          Sadly, the Qt version I am using does not support the use of SC_SpinBoxUp and SC_SpinBoxDown subcontrols :(
                                          I think I will have to rely on the valueChanged() signal for now.

                                          JonBJ Online
                                          JonBJ Online
                                          JonB
                                          wrote on last edited by JonB
                                          #20

                                          @shreya_agrawal said in How to receive mouse events for QDoubleSpinBox:

                                          Sadly, the Qt version I am using does not support the use of SC_SpinBoxUp and SC_SpinBoxDown subcontrols :(

                                          Pardon? State your exact Qt version. Since it is available in Qt4, 5, 6 I doubt your statement.
                                          Show the code you have tried and the error message you get. Don't forget that Python's QStyle.SC_SpinBoxUp is C++'s QStyle::SC_SpinBoxUp....

                                          S 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