如何在Qt中创建自定义3D外观按钮?

时间:2017-05-01 08:41:46

标签: c++ qt qt5 gradient qpainter

我正在尝试创建以下自定义按钮:

custom button 为此,我创建了该类并覆盖了paintEvent

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    QPen pen(Qt::darkGray, 7, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
    painter.setPen(pen);
    painter.drawEllipse(QPointF(width()/2, height()/2), width()/2.1,height()/2.1);

    QPen pen2(Qt::lightGray, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
    painter.setPen(pen2);
    painter.drawEllipse(QPointF(width()/2, height()/2), width()/2.15, height()/2.15);

    QPen pen1(Qt::gray, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
    painter.setPen(pen1);
    painter.drawEllipse(QPointF(width()/2, height()/2), width()/3.5, height()/3.5);
}

但是,我无法在中间创建适当的渐变和图片,如下所示。 你能帮我吗?

2 个答案:

答案 0 :(得分:3)

这里的关键是制作渐变。并且你不能在笔画上做渐变,只能在填充上。这意味着您必须将轮廓实现为填充。

按钮的组件被消化,按照您应该绘制的顺序列出:

enter image description here

请注意只有第一个组件是纯色,其他一切都是渐变色。获得效果的是那些渐变。

为了获得内圈的渐变,你必须使用QPainterPath,先加上外圈,再添加一个略小的内圈,这将有效地在第一个圆圈上打一个洞,你的东西看起来像一个轮廓,但实际上是一个填充,填充,你可以使用渐变。

正如评论中所提到的 - 这涉及很多操作,并不理想。最好将这些按钮作为图像而不是用QPainter绘制它们。

更新:这里有一些帮助,向您展示如何绘制渐变轮廓以实现一些3D错觉:

class Test : public QWidget {
    Q_OBJECT
  public:
    Test() { resize(200, 200); }
    void paintEvent(QPaintEvent *) {
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.fillRect(rect(), Qt::gray);

        QPainterPath p;
        p.addEllipse(rect().center(), 50, 50);
        p.addEllipse(rect().center(), 45, 45);

        QLinearGradient g(QPointF(0, 50), QPointF(0, 150));
        g.setColorAt(0, Qt::white);
        g.setColorAt(1, Qt::black);

        QBrush b(g);
        painter.fillPath(p, b);

        QPainterPath p2;
        p2.addEllipse(rect().center(), 45, 45);
        p2.addEllipse(rect().center(), 40, 40);

        QLinearGradient g1(QPointF(0, 50), QPointF(0, 150));
        g1.setColorAt(0, Qt::black);
        g1.setColorAt(1, Qt::white);

        QBrush b1(g1);
        painter.fillPath(p2, b1);

        QPainterPath p3;
        p3.addEllipse(rect().center(), 40, 40);
        painter.fillPath(p3, b);
    }
};

结果:

enter image description here

答案 1 :(得分:1)

将问题改写为:

如何使用QPainter生成给定的图片?

使用QPainter

  1. 获取按钮的矢量图像,最好是SVG
  2. 查看SVG代码以提取颜色,渐变,大小等。
  3. 使用QPainter重现它们,您将看到对于每个SVG命令,您在QPainte r中具有几乎相等的等效值。 QPainterPath会有所帮助。
  4. 使用QPixmap

    1. 获取按钮的SVG图片
    2. 使用QSvgRenderer生成给定尺寸的QImage,然后将其转换为QPixmap
    3. 在需要时绘制QPixmap
    4. 每个选项的好处:

      • QPixmap更简单,并且可以让您轻松切换按钮美感。
      • QSvgRenderer可让您轻松管理悬停
      • QPainter允许您使用操作系统
      • 覆盖颜色
      • QPainter为您提供更灵活的效果,动画等。