2017-07-26 10 views
5

Trong most examples, tùy biến thanh trượt Qt được thực hiện như thế này (với một stylesheet):Khi tùy biến một thanh trượt với một phong cách trong mã Qt, tay cầm đi ra khỏi rãnh

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

này hoạt động tốt đối với tôi như tốt.

Tôi có một tình huống mà tôi cần phải đặt nền theo chương trình bằng cách sử dụng một bản đồ được tạo theo kiểu tự động. Sử dụng mã dưới đây, đây là cách tôi hoàn thành nó. Vấn đề là khi tôi đang sử dụng Fedora Linux, thanh trượt này hoạt động tốt. Khi tôi đang sử dụng OSX hoặc Windows, thanh trượt sẽ không hoạt động.

Đây là giao diện của OSX. Lưu ý cách xử lý tắt rãnh. Phía bên trái được tùy chỉnh với biểu định kiểu, bên phải được tùy chỉnh với đối tượng Kiểu bên dưới.

Style sheet customization vs customization with a Style object

Tạo thanh trượt và giao cho phong cách:

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

Các mã tùy chỉnh thanh trượt phong cách:

Tiêu đề

#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 

Thực hiện *

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

CẬP NHẬT Mã cho dự án này là open source and available here

+1

Nếu tất cả các bạn đã đùa giỡn với là phong cách, sau đó nó không phải là xử lý mà đi ra khỏi rãnh nhưng bức tranh của bạn. – dtech

+0

Vui lòng giải thích. – 010110110101

+0

Những hình ảnh bạn đã đăng, là những kích thước chính xác? Dường như có sự dịch chuyển trong thanh trượt màu cam về phía bên phải có thể khiến cho đường rãnh không hiển thị chính xác. –

Trả lời

3

Một cuộc gọi đến QCommonStyle :: subControlRect và điều chỉnh chiều rộng/chiều cao là không đủ. Bạn cũng phải tính toán lại vị trí x/y.

Bạn có thể sử dụng therfore QCommonStyle::subControlRect chức năng như tài liệu tham khảo để tính toán hình chữ nhật thích hợp:

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); 
} 
Các vấn đề liên quan