2013-06-28 39 views
19

我正在使用集成了Qt 5.0.1的Visual Studio 2010。我需要在QSlider範圍內選擇。是否有可能獲得兩個手柄?Qt中的範圍滑塊(QSlider中的兩個句柄)

下面是一個圖像,說明我需要什麼。

Example Image

+6

那是不可能的。你需要開發一個自定義小部件。也許試試這個:http://libqxt.bitbucket.org/doc/0.6/qxtspanslider.html –

+0

請建議我該怎麼做。任何片段都意味着要發佈。 – Sivam

+0

我無法在Qt5.0.1中找到QxtSpanslider,無論我是否添加任何插件? – Sivam

回答

9

我有完全相同的問題。我想過使用QxtSpanSlider,雖然它們有漂亮的代碼,但它們不會將代碼保持更新。所以,我決定做我自己的。我沒有花太多時間在這上面,所以有些問題和可能的錯誤。但是,它應該在某種程度上可以將其複製/粘貼到項目中。我希望它能指出你正確的方向。

*請注意,您使用此之前,這裏所有的我發現問題的列表我目前的工作:

  • 第二把手是幾乎沒有第一把手敏感,導致用戶輕微的激動。
  • 某些值是硬編碼的,因此滑塊不像它那樣動態。
  • 第二個句柄不處理(haa ...)負值。

這裏有一個很好的解決方案:

SuperSlider.h

#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); 
}; 

SuperSlider.cpp

//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(); 

} 
+2

爲了編譯它,必須將SuperEventFilter更改爲類頭定義處的頭部中的SliderEventFilter。你可以舉例說明如何使用它?我試圖弄清楚它是如何工作的。 – cauchy

+0

你能解釋一下如何在QT中使用你的班級嗎? –