Qt中的范围滑块(QSlider中的两个手柄)

Qt中的范围滑块(QSlider中的两个手柄),qt,qt5,qslider,Qt,Qt5,Qslider,我需要使用QSlider进行范围选择。有可能得到两个句柄吗?如果没有,有没有代码可以巧妙地处理 下面的图片说明了我需要什么 我也有同样的问题。我考虑过使用QxtSpanSlider,虽然它们有漂亮的代码,但它们的代码不再是最新的。所以,我决定做我自己的。我没有在这上面花太多时间,所以有一些乱七八糟的东西,可能还有bug。但是,它应该位于可以将其复制/粘贴到项目中的位置。我希望它能为你指明正确的方向 *请注意,在使用此功能之前,以下是我发现并正在处理的所有问题的列表: 第二个手柄不如第一个手柄敏

我需要使用
QSlider
进行范围选择。有可能得到两个句柄吗?如果没有,有没有代码可以巧妙地处理

下面的图片说明了我需要什么

我也有同样的问题。我考虑过使用QxtSpanSlider,虽然它们有漂亮的代码,但它们的代码不再是最新的。所以,我决定做我自己的。我没有在这上面花太多时间,所以有一些乱七八糟的东西,可能还有bug。但是,它应该位于可以将其复制/粘贴到项目中的位置。我希望它能为你指明正确的方向

*请注意,在使用此功能之前,以下是我发现并正在处理的所有问题的列表:

  • 第二个手柄不如第一个手柄敏感,导致用户轻微不安
  • 有些值是硬编码的,因此滑块的动态性不如它可能的那样
  • 第二个句柄尚未处理(haa…)负值
这里有一个很好的解决方案:

超滑块

#pragma once

#include "qslider.h"
#include "qlabel.h"


/*
*  Super sick nasty awesome double handled slider! 
*
*   @author Steve
*/
class SuperSliderHandle;

class SuperSlider: public QSlider
{
  Q_OBJECT
public:
  /** Constructor */
  SuperSlider(QWidget *parent = 0);

  /** Store the alternate handle for this slider*/
  SuperSliderHandle *alt_handle;

  /** Overridden mouse release event */
  void mouseReleaseEvent(QMouseEvent *event);

  /** Returns the slider value for the alternate handle */
  int alt_value();

  /** Convenience function for setting the value of the alternate handle */
  void alt_setValue(int value);

  /** Resets the alternate handle to the right side of the slider */
  void Reset();

  /** Used to update the position of the alternate handle through the use of an event filter */
  void alt_update();
signals:
  /** Constructor */
  void alt_valueChanged(int);
};

class SuperEventFilter : public QObject
{
public:
  /** Constructor */
  SliderEventFilter(SuperSlider *_grandParent) 
  {grandParent = _grandParent;};

protected:
  /*
  * overloaded functions for object that inherit from this class
  */
  bool eventFilter(QObject* obj, QEvent* event);

private:
  /** Store the SuperSlider that this event filter is used within. */
  SuperSlider *grandParent;
};

class SuperSliderHandle: public QLabel
{
  Q_OBJECT
public:
  /** Constructor */
  SuperSliderHandle(SuperSlider *parent = 0);

  /** An overloaded mousePressevent so that we can start grabbing the cursor and using it's position for the value */
  void mousePressEvent(QMouseEvent *event);

  /** Returns the value of this handle with respect to the slider */
  int value();

  /** Maps mouse coordinates to slider values */
  int mapValue();

  /** Store the parent as a slider so that you don't have to keep casting it  */
  SuperSlider *parent;

  /** Store a bool to determine if the alternate handle has been activated  */
  bool handleActivated;

private:
  /** Store the filter for installation on the qguiapp */
  SliderEventFilter *filter;

  public slots:
    /** Sets the value of the handle with respect to the slider */
    void setValue(double value);
};
超级滑翔机

//Project
#include "SuperSlider.h"

//Qt
#include <QMouseEvent>
#include "qmimedata.h"
#include "qdrag.h"
#include "qwidgetaction.h"
#include "qapplication.h"
#include "qpixmap.h"
#include "qcursor.h"
#include "qguiapplication.h"
#include "qdir.h"
#include <QProxyStyle>

class SliderProxy : public QProxyStyle
{
public:
  int pixelMetric ( PixelMetric metric, const QStyleOption * option = 0, const QWidget * widget = 0 ) const
  {
    switch(metric) {
    case PM_SliderThickness  : return 25;
    case PM_SliderLength     : return 25;
    default                  : return (QProxyStyle::pixelMetric(metric,option,widget));
    }
  }
};

SuperSlider::SuperSlider(QWidget *parent)
  : QSlider(parent)
{
  //styling
  setOrientation(Qt::Horizontal);
  setAcceptDrops(true);
  SliderProxy *aSliderProxy = new SliderProxy();

  //hard coded path to image :/ sorry 
  QString path = QDir::fromNativeSeparators(ImagesPath("handle.png")); 
  setStyleSheet("QSlider::handle { image: url(" + path + "); }");
  setStyle(aSliderProxy);

  //setting up the alternate handle
  alt_handle = new SuperSliderHandle(this);
  addAction(new QWidgetAction(alt_handle));
  alt_handle->move(this->pos().x() + this->width()- alt_handle->width(), this->pos().y() );

}

SuperSliderHandle::SuperSliderHandle(SuperSlider *_parent)
  : QLabel(_parent)
{
  parent = _parent;
  filter = new SliderEventFilter(parent);

  //styling
  setAcceptDrops(true);
  //hard coded path to image :/ sorry 
  QPixmap pix = QPixmap(ImagesPath("handle.png"));
  pix =  pix.scaled(25, 25, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
  setPixmap(pix);
}

int SuperSlider::alt_value()
{
  return alt_handle->value();
}

void SuperSlider::alt_setValue(int value)
{
  alt_handle->setValue(value);
}

void SuperSlider::mouseReleaseEvent(QMouseEvent *mouseEvent)
{
  if (mouseEvent->button() == Qt::LeftButton) 
  {
    alt_handle->show();
    alt_handle->handleActivated = false;
  }
  mouseEvent->accept();
}

void SuperSlider::alt_update()
{
  QPoint posCursor(QCursor::pos());
  QPoint posParent(mapToParent(mapToGlobal(pos())));
  QPoint point(alt_handle->mapToParent(alt_handle->mapFromGlobal(QCursor::pos())).x(),alt_handle->y());
  int horBuffer = (alt_handle->width());
  bool lessThanMax = mapToParent(point).x() < pos().x()+ width() - horBuffer;
  bool greaterThanMin = mapToParent(point).x() > pos().x();
  if(lessThanMax && greaterThanMin)
    alt_handle->move(point);
  emit alt_valueChanged(alt_value());
}

void SuperSliderHandle::mousePressEvent(QMouseEvent *mouseEvent)
{
  qGuiApp->installEventFilter(filter);
  parent->clearFocus();
}

bool SliderEventFilter::eventFilter(QObject* obj, QEvent* event)
{
  switch(event->type())
  {
  case QEvent::MouseButtonRelease:
    qGuiApp->removeEventFilter(this);
    return true;
    break;
  case QEvent::MouseMove:
    grandParent->alt_update();
    return true;
    break;
  default:
    return QObject::eventFilter(obj, event);
  }
  return false;
}

void SuperSliderHandle::setValue(double value)
{
  double width = parent->width(), position = pos().x();
  double range = parent->maximum() - parent->minimum();
  int location = (value - parent->minimum())/range; 
  location = location *width;
  move(y(),location);
}

int SuperSliderHandle::value()
{
  double width = parent->width(), position = pos().x();
  double value = position/width;
  double range = parent->maximum() - parent->minimum();
  return parent->minimum() + (value * range); 
}
void SuperSlider::Reset()
{
  int horBuffer = (alt_handle->width());
  QPoint myPos = mapToGlobal(pos()); 
  QPoint point(myPos.x() + width() - horBuffer, myPos.y()- alt_handle->height());
  point = alt_handle->mapFromParent(point);

  alt_handle->move(point);
  alt_handle->show();
  alt_handle->raise();

}
//项目
#包括“SuperSlider.h”
//Qt
#包括
#包括“qmimedata.h”
#包括“qdrag.h”
#包括“qwidgetaction.h”
#包括“qapplication.h”
#包括“qpixmap.h”
#包括“qcursor.h”
#包括“qguiapplication.h”
#包括“qdir.h”
#包括
类SliderProxy:public QProxyStyle
{
公众:
int pixelMetric(pixelMetric metric,常量QStyleOption*option=0,常量QWidget*widget=0)const
{
开关(公制){
案例PM_滑块厚度:返回25;
案例PM_滑块长度:返回25;
默认值:返回(QProxyStyle::pixelMetric(公制、选项、小部件));
}
}
};
超级滑翔器::超级滑翔器(QWidget*父)
:QSlider(父级)
{
//造型
设置方向(Qt::水平);
setAcceptDrops(真);
SliderProxy*aSliderProxy=新SliderProxy();
//图像的硬编码路径:/sorry
QString path=QDir::fromNativeSeparators(ImagesPath(“handle.png”);
setStyleSheet(“QSlider::handle{image:url(“+path+”);}”);
setStyle(aSliderProxy);
//设置备用句柄
alt_handle=新的超级滑块handle(此);
addAction(新的QWidgetAction(alt_句柄));
alt_handle->move(this->pos().x()+this->width()-alt_handle->width(),this->pos().y());
}
超级滑块句柄::超级滑块句柄(超级滑块*\u父级)
:QLabel(_父项)
{
家长=_家长;
过滤器=新的SliderEventFilter(父级);
//造型
setAcceptDrops(真);
//图像的硬编码路径:/sorry
QPixmap pix=QPixmap(ImagesPath(“handle.png”);
pix=pix.scaled(25,25,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
setPixmap(pix);
}
int超滑块::alt_值()
{
返回alt_句柄->值();
}
void SuperSlider::alt_setValue(int值)
{
alt_句柄->设置值(值);
}
void SuperSlider::mouseReleaseEvent(QMouseEvent*mouseEvent)
{
if(mouseEvent->button()==Qt::LeftButton)
{
alt_handle->show();
alt_handle->handleActivated=false;
}
mouseEvent->accept();
}
void SuperSlider::alt_update()
{
QPoint posCursor(QCursor::pos());
QPoint posParent(mapToParent(mapToGlobal(pos())));
点点(alt_handle->mapToParent(alt_handle->mapFromGlobal(QCursor::pos()).x(),alt_handle->y());
int horBuffer=(alt_handle->width());
bool lessThanMax=mapToParent(点).x()pos().x();
如果(小于最大值和大于最小值(&G)
alt_手柄->移动(点);
发出alt_值已更改(alt_值());
}
void SuperSliderHandle::MousePresseEvent(QMouseEvent*mouseEvent)
{
qGuiApp->installEventFilter(filter);
父->clearFocus();
}
bool SliderEventFilter::eventFilter(QObject*obj,QEvent*event)
{
开关(事件->类型()
{
案例QEvent::鼠标按钮释放:
qGuiApp->removeEventFilter(此);
返回true;
打破
案例QEvent::MouseMove:
祖父母->alt_update();
返回true;
打破
违约:
返回QObject::eventFilter(对象,事件);
}
返回false;
}
void SuperSliderHandle::setValue(双值)
{
双宽度=父->宽度(),位置=位置().x();
双范围=父级->最大值()-父级->最小值();
int location=(value-parent->minimum())/range;
位置=位置*宽度;
移动(y(),位置);
}
int SuperSliderHandle::value()
{
双宽度=父->宽度(),位置=位置().x();
双值=位置/宽度;
双范围=父级->最大值()-父级->最小值();
返回父项->最小值()+(值*范围);
}
void SuperSlider::Reset()
{
int horBuffer=(alt_handle->width());
QPoint myPos=mapToGlobal(pos());
点(myPos.x()+宽度()-horBuffer,myPos.y()-alt_handle->height());
点=alt_handle->mapFromParent(点);
alt_手柄->移动(点);
alt_handle->show();
alt_手柄->升起();
}

这是不可能的。您需要开发一个自定义小部件。也许试试这个:请告诉我怎么做。任何代码片段都表示请发布。我无法在Qt5.0.1中找到QxtSpanslider,是否添加了任何插件?您需要使用Qxt库。或者使用此库来编译它,SuperEventFilter必须在类定义的标题中更改为SliderEventFilter。你能举例说明如何使用它吗?我正在试图弄清楚它是如何工作的。你能解释一下如何在QT中使用你的类吗?在垂直模式下,第二个处理程序只能水平移动。