在most examples中,自定义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上时,滑块手柄会脱离goove。
这是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);
}
更新 该项目的代码是open source and available here
答案 0 :(得分:4)
调用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);
}