HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

QSlider direct jump on click

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
directclickqsliderjump

Problem

By default, QSlider move his thumbtrack by a value belonging to the singleStep() prop on mouse click. To make thumbtrack jump directly at the mouse click point, we need to create a new class inherited by QSlider.

Header file (.h):

#include 
#include 
#include 
#include 
#include 
#include 
#ifndef QIMPROVEDSLIDER_H
#define QIMPROVEDSLIDER_H

class QImprovedSlider : public QSlider
{
    Q_OBJECT
protected:
    void mousePressEvent(QMouseEvent *event);

public:
    explicit QImprovedSlider(QWidget *parent = 0);

    ~QImprovedSlider();

public slots:

private:

private slots:

signals:
    void onClick(int value);
};

#endif // QIMPROVEDSLIDER_H


Source file (.cpp):

```
#include "QImprovedSlider.h"

QImprovedSlider::QImprovedSlider(QWidget *parent) :
QSlider(parent)
{

}

QImprovedSlider::~QImprovedSlider()
{
}

void QImprovedSlider::mousePressEvent(QMouseEvent *event) {
QStyleOptionSlider opt;
initStyleOption(&opt);
QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);

if (event->button() == Qt::LeftButton &&
!sr.contains(event->pos())) {
int newVal;
if (orientation() == Qt::Vertical) {
double halfHandleHeight = (0.5 * sr.height()) + 0.5;
int adaptedPosY = height() - event->y();
if ( adaptedPosY height() - halfHandleHeight )
adaptedPosY = height() - halfHandleHeight;
double newHeight = (height() - halfHandleHeight) - halfHandleHeight;
double normalizedPosition = (adaptedPosY - halfHandleHeight) / newHeight ;

newVal = minimum() + (maximum()-minimum()) * normalizedPosition;
} else {
double halfHandleWidth = (0.5 * sr.width()) + 0.5;
int adaptedPosX = event->x();
if ( adaptedPosX width() - halfHandleWidth )
adaptedPosX = width() - halfHandleWidth;
double newWidth = (width() - halfHandleWidth) - halfHandleWidth;
double normalizedPosition = (adaptedPosX - halfHandleWidth) / newWidt

Solution

One issue I see, that has to do with functionality: since you are working with doubles, but your end values are integers, perhaps you should round the result.

The code above will set the handle one step before the end when you position the mouse at the end.

To fix, round the new position: replace

newVal = minimum() + ((maximum()-minimum()) * normalizedPosition);


with

newVal = minimum() + qRound((maximum()-minimum()) * normalizedPosition);

Code Snippets

newVal = minimum() + ((maximum()-minimum()) * normalizedPosition);
newVal = minimum() + qRound((maximum()-minimum()) * normalizedPosition);

Context

StackExchange Code Review Q#140308, answer score: 2

Revisions (0)

No revisions yet.