我创建了一个继承自 QSlider 的类,我想在滑块(抓取器)上绘制图片,而不是显示普通的图片。
如何做?
您可以在小部件的 paintEvent 方法中执行此操作。这允许您重新绘制小部件的全部或仅一部分。
样式表和
paintEvent
的组合可用于自定义句柄,而无需重新实现鼠标事件。
如果绘图区域超出手柄的几何形状,它将不会接收鼠标单击,因此我使用样式表使其大小与正在绘制的区域相同。
这里是一个加宽手柄并使其成为圆角矩形的示例,要调整它,需要修改样式表和
paintEvent
:
#include <QApplication>
#include <QtWidgets>
class MSlider : public QSlider
{
public:
QRect handleRect;
MSlider(QWidget *parent = nullptr)
{
setStyleSheet("QSlider"
"{"
"width: 52px;"
"}"
"QSlider::groove:vertical "
"{"
//border and width are necessary
//adjust them with care
"border: 1px;"
"width: 5px;"
"background: white;"
"}"
"QSlider::add-page:vertical "
"{"
"background: white;"
"}"
"QSlider::sub-page:vertical "
"{"
"background: green;"
"}"
"QSlider::handle:vertical "
"{"
"height: 24px;"
//width does not make a difference
//use margin instead to control width
"margin: -1px -24px;"
"}");
}
protected:
void paintEvent(QPaintEvent *event) override
{
//paint the slider before painting your custom handle or it might cover it
QSlider::paintEvent(event);
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing);
QStyleOptionSlider opt;
initStyleOption(&opt);
//get handle rect
//use qDebug to check it when adjusting stylesheet
handleRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
painter.setBrush(Qt::black);
painter.setPen(Qt::black);
painter.drawRoundedRect(handleRect, 5, 5);
}
};
int main(int argc,char*argv[])
{
QApplication a(argc, argv);
MSlider slider;
slider.show();
return a.exec();
}
结果:
注意: 此解决方案未在水平滑块上进行测试。
了解更多:
Viet提供的答案:
void InheritedSlider::paintEvent(QPaintEvent *event)
{
// uncomment to draw the parent first. Comment out to just ignore it.
//QSlider::paintEvent(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
//painter.translate(width() / 2, height() / 2);
//painter.scale(100 / 200.0, 100 / 200.0);
QPainterPath volPath;
volPath.moveTo(60.0, 40.0);
volPath.arcTo(20.0, 20.0, 40.0, 40.0, 0.0, 360.0);
volPath.moveTo(40.0, 40.0);
volPath.lineTo(40.0, 80.0);
volPath.lineTo(80.0, 80.0);
volPath.lineTo(80.0, 40.0);
volPath.closeSubpath();
painter.drawPath(volPath);
}