使用代码中的样式自定义Qt滑块时,手柄会脱离凹槽

010110110101

大多数示例中,自定义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;}");

这对我也很好。

我遇到一种情况,需要使用动态创建的像素图以编程方式设置背景。使用下面的代码,这就是我完成它的方式。问题是当我使用Fedora Linux时,此滑块可以正常工作。当我在OSX或Windows上时,滑块手柄会松动。

这是OSX上的样子。注意手柄如何脱离凹槽。左侧使用样式表自定义,右侧使用下面的Style对象自定义。

样式表自定义与使用样式对象进行自定义

创建滑块并指定样式:

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

更新此项目的代码是开源的,可在此处获得

威曼

调用QCommonStyle :: subControlRect并调整宽度/高度是不够的。您还必须重新计算x / y位置。

因此,您可以使用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);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章