默认情况下,QSlider通过鼠标单击singleStep()支柱的值移动他的大拇指轨迹。要使拇指轨迹直接跳转到鼠标单击点,我们需要创建一个由QSlider继承的新类。
头文件(.h):
#include <QWidget>
#include <QAbstractSlider>
#include <QSlider>
#include <QMouseEvent>
#include <QStyle>
#include <QStyleOptionSlider>
#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源文件(.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 < halfHandleHeight )
adaptedPosY = halfHandleHeight;
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 < halfHandleWidth )
adaptedPosX = halfHandleWidth;
if ( adaptedPosX > width() - halfHandleWidth )
adaptedPosX = width() - halfHandleWidth;
double newWidth = (width() - halfHandleWidth) - halfHandleWidth;
double normalizedPosition = (adaptedPosX - halfHandleWidth) / newWidth ;
newVal = minimum() + ((maximum()-minimum()) * normalizedPosition);
}
if (invertedAppearance())
this->setValue( maximum() - newVal );
else
this->setValue(newVal);
event->accept();
}
else {
QSlider::mousePressEvent(event);
}
emit onClick(this->value());
}这段代码运行良好,所以不是坏代码。有什么办法可以改善这一点吗?也许是为了区分直接跳转和手柄拖动。
发布于 2017-03-22 19:46:02
我看到的一个问题是,这与功能有关:因为您使用的是双值,但是您的结束值是整数,也许您应该舍入结果。
当您将鼠标放在末尾时,上面的代码将在结束前一步设置句柄。
若要修复,请绕过新位置:替换
newVal = minimum() + ((maximum()-minimum()) * normalizedPosition);使用
newVal = minimum() + qRound((maximum()-minimum()) * normalizedPosition);发布于 2016-10-01 21:50:06
if (invertedAppearance()) {
this->setValue( maximum() - newVal );
} else {
this->setValue(newVal);
}您不应该在没有Curly的情况下发布if/else语句。这种风格为您打开了大量的bug,而事后的想法是:让您或其他开发人员添加到这段代码中很麻烦。
例如,假设您正在编辑或调试代码,并决定注释掉一行:
if (invertedAppearance())
this->setValue( maximum() - newVal );
else
// this->setValue(newVal);
event->accept();你看到问题了吗?
https://codereview.stackexchange.com/questions/140308
复制相似问题