2017-07-26 66 views
5

most examples,定製Qt的滑塊這樣做(用樣式表):當定製Qt的滑蓋代碼樣式,手柄熄滅槽

mySlider = new QSlider(centralWidget); 
mySlider->setObjectName(QStringLiteral("mySlider")); 
mySlider->setGeometry(QRect(645, 678, 110, 21)); 
mySlider->setOrientation(Qt::Horizontal); 
mySlider->setStyleSheet("QSlider::groove:horizontal {background-image:url(:/main/graphics/mySliderBackround.png);}" 
       "QSlider::handle:horizontal {background-image:url(:/main/graphics/mySliderHandle.png); height:21px; width: 21px;}"); 

這對我的作品罰款好。

我有一種情況,我需要使用dyamically創建的pixmap以編程方式設置背景。使用下面的代碼,這是我完成它的方式。 問題是,當我在Fedora Linux上時,這個滑塊工作正常。當我在OSX或Windows上時,滑塊手柄會熄滅。

下面是它在OSX上的外觀。注意手柄如何脫離凹槽。左側是用樣式表定製的,右側是用下面的Style對象定製的。

Style sheet customization vs customization with a Style object

創建滑塊和分配方式:

mySlider = new QSlider(centralWidget); 
mySlider->setObjectName(QStringLiteral("mySlider")); 
mySlider->setGeometry(QRect(645, 678, 110, 21)); 
mySlider->setOrientation(Qt::Horizontal); 
mySlider->setStyle(new MySliderStyle(mySlider->style())); 

定製的滑蓋造型代碼:

#ifndef MYSTYLE_H 
#define MYSTYLE_H 

#include <QObject> 
#include <QWidget> 
#include <QProxyStyle> 
#include <QPainter> 
#include <QStyleOption> 
#include <QtWidgets/QCommonStyle> 

class MySliderStyle : public QProxyStyle 
{ 
     private: 
    QPixmap groovePixmap; 
    QPixmap handlePixmap; 

     public: 
    LightingSliderStyle(QStyle *style) 
     : QProxyStyle(style) 
    { 
     setColor(QColor::fromRgba(0)); 

     this->handlePixmap = <snip initialize the pixmap>; 
     this->grooveMaskPixmap = <snip initialize the pixmap>; 
    } 

    void drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const; 

    QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const; 

    void setColor(QColor color); 
}; 

#endif // MYSTYLE_H 

實施*

#include "MySliderStyle.h" 

QRect MySliderStyle::subControlRect(ComplexControl control, 
         const QStyleOptionComplex *option, 
         SubControl subControl, 
         const QWidget *widget) const 
{ 
    QRect rect; 

    rect = QCommonStyle::subControlRect(control, option, subControl, widget); 

    if (control == CC_Slider && subControl == SC_SliderHandle) 
    { 
     // this is the exact pixel dimensions of the handle png files 
     rect.setWidth(21); 
     rect.setHeight(21); 
    } 
    else if (control == CC_Slider && subControl == SC_SliderGroove) 
    { 
     // this is the exact pixel dimensions of the slider png files 
     rect.setWidth(widget->width()); 
     rect.setHeight(widget->height()); 
    } 

    return rect; 
} 

void MySliderStyle::drawComplexControl(QStyle::ComplexControl control, 
         const QStyleOptionComplex *option, 
         QPainter *painter, 
         const QWidget *widget) const 
{ 
    if (control == CC_Slider) 
    { 
     if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) 
     { 
      QRect groove = subControlRect(CC_Slider, slider, SC_SliderGroove, widget); 
      QRect handle = subControlRect(CC_Slider, slider, SC_SliderHandle, widget); 

      if ((slider->subControls & SC_SliderGroove) && groove.isValid()) 
      { 
       Qt::BGMode oldMode = painter->backgroundMode(); 
       painter->setBackgroundMode(Qt::TransparentMode); 
       painter->drawPixmap(groove, groovePixmap); 
       painter->setBackgroundMode(oldMode); 
      } 

      if ((slider->subControls & SC_SliderHandle) && handle.isValid()) 
      { 
       Qt::BGMode oldMode = painter->backgroundMode(); 
       painter->setBackgroundMode(Qt::TransparentMode); 
       painter->drawPixmap(handle, handlePixmap); 
       painter->setBackgroundMode(oldMode); 
      } 
     } 
    } 
    else 
    { 
     QProxyStyle::drawComplexControl(control, option, painter, widget); 
    } 
} 

void MySliderStyle::setColor(QColor color) 
{ 
    QImage myGrooveImage; 

    // <snip> 
    // Code to create the custom pixmap 
    // <snip> 

    groovePixmap = QPixmap::fromImage(myGrooveImage); 
} 

UPDATE 該項目的代碼是open source and available here

+1

如果您有玩弄都是造型,那麼它是不是熄滅了槽,但你的畫手柄。 – dtech

+0

請解釋。 – 010110110101

+0

您發佈的圖片是否具有精確的尺寸?似乎有橙色滑塊向右移動,可能導致凹槽無法正常顯示。 –

回答

3

到QCommonStyle :: subControlRect呼叫並調整寬度/高度是不夠的。您還必須重新計算x/y位置。

可以therfore使用QCommonStyle::subControlRect功能作爲參考來計算合適的矩形:

QRect LightingSliderStyle::subControlRect(ComplexControl control, 
         const QStyleOptionComplex *option, 
         SubControl subControl, 
         const QWidget *widget) const 
{ 
    if (control == CC_Slider) 
    { 
     if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) { 
      QRect ret; 

      int tickOffset = 0; 
      int thickness = 21;  // height 
      int len = 21;   // width 

      switch (subControl) { 
      case SC_SliderHandle: { 
       int sliderPos = 0; 
       bool horizontal = slider->orientation == Qt::Horizontal; 
       sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum+1, 
                slider->sliderPosition, 
                (horizontal ? slider->rect.width() 
                   : slider->rect.height()) - len, 
                slider->upsideDown); 
       if (horizontal) 
        ret.setRect(slider->rect.x() + sliderPos, slider->rect.y() + tickOffset, len, thickness); 
       else 
        ret.setRect(slider->rect.x() + tickOffset, slider->rect.y() + sliderPos, thickness, len); 
       break; } 
      case SC_SliderGroove: 
       if (slider->orientation == Qt::Horizontal) 
        ret.setRect(slider->rect.x(), slider->rect.y() + tickOffset, 
           slider->rect.width(), thickness); 
       else 
        ret.setRect(slider->rect.x() + tickOffset, slider->rect.y(), 
           thickness, slider->rect.height()); 
       break; 
      default: 
       break; 
      } 
      return visualRect(slider->direction, slider->rect, ret); 
     } 
    } 

    return QCommonStyle::subControlRect(control, option, subControl, widget); 
}