【QT小记】使用QPainter绘制各种基本图形

心中有坐标 万物皆可Paint

  • 封装LQCanvas类绘制各种基本图形
// lqcanvas.h
#ifndef LQCANVAS_H
#define LQCANVAS_H

#include <QWidget>
#include <QMetaType>


class LQCanvas : public QWidget
{
    Q_OBJECT
public:
    explicit LQCanvas(QWidget *parent = nullptr);

public:
    void setBackgroundColor(const QColor &color);
    void setPenColor(const QColor&color);
    void setPenWidth(int width);
    void setType(const QString &type);

private:
    void paintLuffy(QPainter &painter);

protected:
    void paintEvent(QPaintEvent *event) override;

private:
    QColor m_backgroundColor;
    QColor m_penColor;
    int m_penWidth;
    QString m_type;
};

#endif // LQCANVAS_H

// lqcanvas.cpp
#include "lqcanvas.h"

#include <QPainter>

LQCanvas::LQCanvas(QWidget *parent) : QWidget(parent)
{
    m_backgroundColor = QColor(0, 0, 0);
    m_penColor = QColor(255, 255, 255);
    m_penWidth = 2;
    m_type = "点";
}

void LQCanvas::setBackgroundColor(const QColor &color)
{
    m_backgroundColor = color;
}

void LQCanvas::setPenColor(const QColor &color)
{
    m_penColor = color;
}

void LQCanvas::setPenWidth(int width)
{
    m_penWidth = width;
}

void LQCanvas::setType(const QString &type)
{
    m_type = type;
    update();
}

void LQCanvas::paintLuffy(QPainter &painter)
{
    QPen pen;
    pen.setColor(QColor(0, 0, 0));
    pen.setWidth(0);
    painter.setPen(pen);

    int headRadius = 252 >> 1;
    int headRectX = 200;
    int headRectY = 100;
    int headCenterX = headRectX + headRadius;
    int headCenterY = headRectY + headRadius;
    QRect headRect(headRectX, headRectY, headRadius * 2, headRadius * 2);

    // 十字骨头
    int boneRectWidth = 360;
    int boneRectHeight = 300;
    int boneRectX = headCenterX - boneRectWidth / 2;
    int boneRectY = headCenterY + 50 - boneRectHeight / 2;
    QRect boneRect(boneRectX, boneRectY, boneRectWidth, boneRectHeight);
    QPoint point1(boneRectX, boneRectY);
    QPoint point2(boneRectX + boneRectWidth, boneRectY);
    QPoint point3(boneRectX + 30, boneRectY + boneRectHeight - 20);
    QPoint point4(boneRectX + boneRectWidth - 30, boneRectY + boneRectHeight - 20);
    pen.setWidth(36);
    pen.setColor(QColor(255, 255, 255));
    painter.setPen(pen);
    painter.drawLine(point1, point4);
    painter.drawLine(point2, point3);
//    painter.drawRect(boneRect);

    pen.setWidth(0);
    pen.setColor(QColor(0, 0, 0));
    painter.setPen(pen);

#if 1
    // 嘴巴
    int mouseRadius = headRadius + 50;
    int mouseRectX = headCenterX - mouseRadius;
    int mouseRectY = headCenterY - mouseRadius;
    QRect mouseRect(mouseRectX, mouseRectY, mouseRadius * 2, mouseRadius * 2);
    painter.setBrush(QBrush(QColor(255, 255, 255)));

    // 下巴
    int pawRectWidth = 150;
    int pawRectHeight = 120;
    int pawRectX = headCenterX - pawRectWidth / 2;
    int pawRectY = headCenterY + mouseRadius - 80;
    QRect pawRect(pawRectX, pawRectY, pawRectWidth, pawRectHeight);
    painter.drawChord(pawRect, 0, -180 * 16);

    painter.drawPie(mouseRect, -65 * 16, -50 * 16);


    // 骷髅头下半部分
    painter.setBrush(QBrush(QColor(255, 255, 255)));
    painter.drawChord(headRect, 0, -180 * 16);

    // 眼睛
    painter.setBrush(QBrush(QColor(0, 0, 0)));
    int eyeToCenterX = 70;
    int eyeToCenterY = 20;
    int eyeRadius = 30;
    QRect leftEyeRect(headCenterX - eyeToCenterX, headCenterY + eyeToCenterY, eyeRadius * 2, eyeRadius * 2);
    QRect rightEyeRect(headCenterX + eyeToCenterX - eyeRadius * 2, headCenterY + eyeToCenterY, eyeRadius * 2, eyeRadius * 2);
    painter.drawChord(leftEyeRect, 0, 360 * 16);
    painter.drawChord(rightEyeRect, 0, 360 * 16);

    // 鼻子
    int noseWidth = 26;
    int noseHeight = 18;
    int noseX = headCenterX - noseWidth / 2;
    int noseY = headCenterY + 90;
    QRect noseRect(noseX, noseY, noseWidth, noseHeight);
    painter.drawChord(noseRect, 0, 360 * 16);

    // 草帽
    painter.setBrush(QBrush(QColor(255, 0, 0)));
    painter.drawChord(headRect, 0, 180 * 16);
    painter.setBrush(QBrush(QColor(255, 255, 0)));
    painter.drawChord(headRect, 15 * 16, 150 * 16);


    // 帽檐
    int capRectWidth = headRadius * 2 + 80;
    int capRectHeight = 18;
    int capRectX = headCenterX - capRectWidth / 2;
    int capRectY = headCenterY - capRectHeight / 2;
    QRect capRect(capRectX, capRectY, capRectWidth, capRectHeight);
    painter.setBrush(QBrush(QColor(255, 255, 0)));
    painter.drawRoundedRect(capRect, capRectHeight / 2, capRectHeight / 2);
#endif
}

void LQCanvas::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    // 获取中心点
    int width = this->width();
    int height = this->height();
    int centerX = width >> 1;
    int centerY = height >> 1;


    QPainter painter(this);

    // 设置反走样
    painter.setRenderHint(QPainter::Antialiasing);

    // 绘制背景
    painter.setBrush(QBrush(m_backgroundColor));
    painter.drawRect(rect());

    // 设置画笔

    QPen pen;
    pen.setColor(m_penColor);
    pen.setWidth(m_penWidth);
    painter.setPen(pen);

    // 取消填充色
    painter.setBrush(QBrush());

    if ("点" == m_type) {
        painter.drawPoint(centerX, centerY);
    } else if ("线" == m_type) {
        painter.drawLine(centerX, centerY - 20, centerX, centerY + 20);
        painter.drawLine(centerX - 20, centerY, centerX + 20, centerY);
    } else if ("三角形" == m_type) {
        // 没有绘制三角形的接口,需调用绘制多边形的接口
        QPoint point[3];
        point[0] = QPoint(centerX, centerY - 20);
        point[1] = QPoint(centerX - 20, centerY + 20);
        point[2] = QPoint(centerX + 20, centerY + 20);
        painter.drawPolygon(point, 3);
    } else if ("正方形" == m_type) {
        QRect rect(centerX - 20, centerY - 20, 40, 40);
        painter.drawRect(rect);
    } else if ("长方形" == m_type) {
        QRect rect(centerX - 40, centerY - 20, 80, 40);
        painter.drawRect(rect);
    } else if ("圆形" == m_type) {
        // 在正方形中绘制会则为圆形
        QRect rect(centerX - 20, centerY - 20, 40, 40);
        painter.drawEllipse(rect);
    } else if ("椭圆形" == m_type) {
        // 在长方形中绘制则为椭圆形
        QRect rect(centerX - 40, centerY - 20, 80, 40);
        painter.drawEllipse(rect);
    } else if ("多边形" == m_type) {
        QPoint point[10];
        point[0] = QPoint(centerX - 60, centerY);
        point[1] = QPoint(centerX - 20, centerY);
        point[2] = QPoint(centerX, centerY - 40);
        point[3] = QPoint(centerX + 20, centerY);
        point[4] = QPoint(centerX + 60, centerY);
        point[5] = QPoint(centerX + 20, centerY + 20);
        point[6] = QPoint(centerX + 50, centerY + 50);
        point[7] = QPoint(centerX, centerY + 20);
        point[8] = QPoint(centerX - 50, centerY + 50);
        point[9] = QPoint(centerX - 20, centerY + 20);
        painter.drawPolygon(point, 10);
    } else if ("扇形" == m_type) {
        // 通过矩形来绘制的
        // 3点钟的方向为 0 度,顺时针方向为负值,逆时针方向为正值, 360度 = 5760份,1度为16份
        QRect rect(centerX - 20, centerY - 20, 40, 40);
        int startAngle = 0;  //起始角度
        int spanAngle = 90 * 16;  //终点角度 - 起始角度,正值:逆时针方向
        painter.drawPie(rect, startAngle, spanAngle);
    } else if ("弧形" == m_type) {
        // 通过矩形来绘制的
        // 3点钟的方向为 0 度,顺时针方向为负值,逆时针方向为正值, 360度 = 5760份,1度为16份
        QRect rect(centerX - 20, centerY - 20, 40, 40);
        int startAngle = 0;  //起始角度
        int spanAngle = 90 * 16;  //终点角度 - 起始角度,正值:逆时针方向
        painter.drawArc(rect, startAngle, spanAngle);
    } else if ("弦" == m_type) {
        // 通过矩形来绘制的
        // 3点钟的方向为 0 度,顺时针方向为负值,逆时针方向为正值, 360度 = 5760份,1度为16份
        QRect rect(centerX - 20, centerY - 20, 40, 40);
        int startAngle = 0;  //起始角度
        int spanAngle = 90 * 16;  //终点角度 - 起始角度,正值:逆时针方向
        painter.drawChord(rect, startAngle, spanAngle);
    } else if ("圆角矩形" == m_type) {
        QRect rect(centerX - 20, centerY - 20, 40, 40);
        painter.drawRoundedRect(rect, 5, 5);
    } else if ("路径" == m_type) {
        QPainterPath path;
        path.moveTo(centerX, centerY);
        path.lineTo(centerX, centerY - 40);
        path.cubicTo(centerX + 60, centerY - 60, centerX + 20, centerY - 20, centerX + 80, centerY +80);
        painter.drawPath(path);
    } else if ("文本" == m_type) {
        // 设置字体
        QFont font;
        font.setPixelSize(24);
        painter.drawText(centerX, centerY, "Sevenlin");
    } else if ("图片" == m_type) {
        QPixmap pix = QPixmap("./luffy0505.jpg");
        painter.drawPixmap(rect(), pix);
    } else if ("路飞" == m_type) {
        paintLuffy(painter);
    }
}
  • LQCanvas的使用
// .h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_comboBoxShapeType_currentIndexChanged(int index);

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

// .cpp
#include "widget.h"
#include "ui_widget.h"
#include "lqcanvas.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    setWindowTitle("Sevenlin_QPainter练习小记");

    QStringList type{"路飞", "点", "线", "三角形", "正方形", "长方形", "圆形", 
                     "椭圆形", "多边形", "扇形", "弧形", "弦", "圆角矩形", "路径", 
                     "文本", "图片"};
    ui->comboBoxShapeType->addItems(type);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_comboBoxShapeType_currentIndexChanged(int index)
{
    Q_UNUSED(index)
    QString type = ui->comboBoxShapeType->currentText();
    ui->widgetCavans->setType(type);
}

  • 简单绘制草帽海贼旗一枚
    在这里插入图片描述
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QT使用QPainter绘制带有标题、轴线的图表可以采用以下步骤: 1. 创建一个QWidget或QFrame作为绘制图表的容器。 2. 重写QWidget或QFrame的paintEvent方法,在该方法中使用QPainter进行绘制。 3. 绘制图表的标题,可以使用QPainter的drawText方法。 4. 绘制图表的轴线,可以使用QPainter的drawLine方法。 5. 绘制图表的坐标轴刻度和标签,可以使用QPainter的drawText方法。 6. 绘制图表的数据点,可以使用QPainter的drawEllipse或drawRect方法。 7. 在数据点之间绘制曲线或直线,可以使用QPainter的drawPolyline方法。 8. 最后,调用QWidget或QFrame的update方法,触发paintEvent方法进行绘制。 具体实现方法可以参考以下代码: ```cpp void MyWidget::paintEvent(QPaintEvent *) { QPainter painter(this); // 绘制标题 painter.drawText(rect(), Qt::AlignTop | Qt::AlignHCenter, "My Chart"); // 绘制坐标轴 painter.drawLine(QPointF(50, height() - 50), QPointF(width() - 50, height() - 50)); // x轴 painter.drawLine(QPointF(50, height() - 50), QPointF(50, 50)); // y轴 // 绘制坐标轴刻度和标签 painter.drawText(QPointF(50, height() - 30), "0"); painter.drawText(QPointF(width() - 70, height() - 30), "100"); painter.drawText(QPointF(20, height() - 50), "0"); painter.drawText(QPointF(20, 70), "100"); // 绘制数据点和连接线 QVector<QPointF> points = {{75, height() - 75}, {100, height() - 50}, {125, height() - 75}, {150, height() - 100}, {175, height() - 125}, {200, height() - 150}}; painter.setPen(Qt::red); painter.setBrush(Qt::red); for (const auto &point : points) { painter.drawEllipse(point, 5, 5); } painter.drawPolyline(points); // 更新绘制 update(); } ``` 在该代码中,我们创建了一个QWidget作为绘制图表的容器,并重写了其paintEvent方法进行绘制。在绘制过程中,我们使用QPainter进行绘制绘制了图表的标题、坐标轴、坐标轴刻度和标签、数据点和连接线。最后,我们调用QWidget的update方法,触发paintEvent方法进行绘制

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值