如何绘制图片而不是QSlider的滑块?

发布于 2024-08-14 15:26:33 字数 70 浏览 5 评论 0原文

我创建了一个继承自 QSlider 的类,我想在滑块(抓取器)上绘制一张图片,而不是显示普通的图片。

怎么做呢?

I have created a class that inherits from QSlider and I want to draw a picture on the slider (grabber) instead of showing the plain one.

How to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

生死何惧 2024-08-21 15:26:33

您可以在小部件的 paintEvent 方法中执行此操作。这允许您重绘所有或仅部分小部件。

You can do it into the paintEvent method of the widget. This allows you to redraw all or only a part of the widget.

楠木可依 2024-08-21 15:26:33

样式表和 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();
}

结果:

正在拖动的自定义滑块手柄


注意: 此解决方案未在水平滑块上进行测试。


了解更多:

A combination of stylesheets and paintEvent could be used to customize the handle, without reimplementing mouse events.

If the drawing area exceeds the handle's geometry, it will not pick up mouse clicks, therefore I'm using stylesheets to make it the same size as the area being drawn.

Here's an example that widens the handle and makes it a rounded rect, to adjusted it, it's needed to modify both stylesheets and 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();
}

Result:

Custom slider handle being dragged


Note: This solution is not tested on horizontal sliders.


For more:

七色彩虹 2024-08-21 15:26:33

越南提供的答案:

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

Answer provided by 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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文