Search code examples
c++qtmouseeventqdial

How can I make my QDial react to a different mouse event than the one predefined?


I have a subclass of a QDial and I want to change the values by moving my mouse up and down. At the moment, the basic implementation allows you to do a circular movement with the mouse to change the values. But I'd like to change them by moving my mouse either up (let's say that once I have pressed my dial, I'll move my mouse to the top of my screen) or down (to the bottom of the screen).

Here's a picture (beware, MS Paint skills ahead) of what I want to achieve. On the left, it's the basic behavior, and on the right, the behavior that I'd like to have.

                                        enter image description here

I don't see how I could get that with mousePressEvent or mouseMoveEvent. Does anybody have an idea?


Solution

  • Unless I've misunderstood what you want this should be fairly straight forward with something like...

    class dial: public QDial {
    public:
      dial (QWidget *parent = nullptr)
        : QDial(parent)
        , m_dragging(false)
        , m_scale_factor(1.0f)
        {}
    protected:
      virtual void mousePressEvent (QMouseEvent *event) override
        {
          m_mouse_press_point = event->pos();
          m_dragging = true;
          m_base_value = value();
        }
      virtual void mouseReleaseEvent (QMouseEvent *event) override
        {
          m_dragging = false;
        }
      virtual void mouseMoveEvent (QMouseEvent *event) override
        {
          if (m_dragging) {
            int new_value = m_base_value + m_scale_factor * (m_mouse_press_point.y() - event->y());
            setValue(new_value);
          }
        }
    private:
      bool   m_dragging;
      QPoint m_mouse_press_point;
      int    m_base_value;
      float  m_scale_factor;
    };
    

    You'll probably want to adjust m_scale_factor based on screen resolution or similar.

    If you don't want to subclass QDial the same logic could be implemented with a stateful event filter.