Qt 绘制直线箭头

一、概述

Qt 中没有直接支持绘制直线箭头,所以必须自己用算法画出箭头。

二、算出箭头点的坐标

利用数学函数算出角度,继而算出坐标。

三、代码

// ----------------------------------------
void paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    QPen pen;
    pen.setColor(Qt::black);
    painter.setPen(pen);

    int lineHStartPos; // 连接线起点水平位置
    int lineVStartPos; // 连接线起点垂直位置
    int lineHEndPos;   // 连接线终点水平位置
    int lineVEndPos;   // 连接线终点垂直位置

    lineHStartPos = 0;
    lineVStartPos = 0;

    lineHEndPos = 100;
    lineVEndPos = 100;

    QLineF line(lineHStartPos, lineVStartPos, lineHEndPos, lineVEndPos);
    painter.drawLine(line);

    // 箭头的两点坐标
    double x1, y1, x2, y2;

    // 求得箭头两点坐标
    CalcVertexes(lineHStartPos, lineVStartPos, lineHEndPos, lineVEndPos, x1, y1, x2, y2);
    painter.drawLine(lineHEndPos, lineVEndPos, x1, y1); // 绘制箭头一半
    painter.drawLine(lineHEndPos, lineVEndPos, x2, y2); // 绘制箭头另一半
}

// ---------------------------------------------------------------------------------------------------------------------------------------
void CalcVertexes(double startX, double startY, double endX, double endY, double& x1, double& y1, double& x2, double& y2)
{
    /*
     * @brief 求得箭头两点坐标
     */

    double arrowLength = 10;      // 箭头长度,一般固定
    double arrowDegrees = 0.5;    // 箭头角度,一般固定

    // 求 y / x 的反正切值
    double angle = atan2(endY - startY, endX - startX) + 3.1415926;

    // 求得箭头点 1 的坐标
    x1 = endX + arrowLength * cos(angle - arrowDegrees);
    y1 = endY + arrowLength * sin(angle - arrowDegrees);

    // 求得箭头点 2 的坐标
    x2 = endX + arrowLength * cos(angle + arrowDegrees);
    y2 = endY + arrowLength * sin(angle + arrowDegrees);
}

四、结果

Qt中,你可以使用QPainter类以及相关的形状绘制功能来创建箭头图形。QPainter提供了一种灵活的方式来绘制各种形状,包括简单的直线、弧线和自定义路径,可以组合成箭头。这里是一个基本步骤: 1. 创建一个QGraphicsScene或者QWidget作为画布。 2. 获取QPainter实例,关联到这个画布。 3. 使用`drawLine()`或`drawPolygon()`等函数绘制基础线条,然后通过`save()`和`restore()`保存并恢复当前的绘图状态,添加旋转和平移操作来形成箭头。 4. 示例代码: ```cpp void drawArrow(QPainter &painter, QPointF start, QPointF end, int width) { painter.save(); // 箭头头部 painter.drawLine(start.x(), start.y(), end.x(), end.y()); QPointF tailPos = end + QVector2D(end.x() - start.x(), -(end.y() - start.y())); painter.drawLine(end, tailPos); // 上下左右箭头方向 if (width > 0) { // 右侧箭头 painter.drawPolygon(QPolygonF({QPointF(end.x() + width, end.y()), QPointF(end.x() + width * 0.7, end.y() - width), QPointF(end.x() + width * 0.3, end.y() - width)})); // 左侧箭头 painter.drawPolygon(QPolygonF({QPointF(end.x() - width, end.y()), QPointF(end.x() - width * 0.7, end.y() - width), QPointF(end.x() - width * 0.3, end.y() - width)})); // 下部箭头 QPointF downPos = end + QVector2D(0, -width); painter.drawPolygon(QPolygonF({QPointF(end.x(), downPos.y()), QPointF(end.x() - width * 0.5, downPos.y() + width), QPointF(end.x() + width * 0.5, downPos.y() + width)})); // 上部箭头 QPointF upPos = end + QVector2D(0, width); painter.drawPolygon(QPolygonF({QPointF(end.x(), upPos.y()), QPointF(end.x() - width * 0.5, upPos.y() - width), QPointF(end.x() + width * 0.5, upPos.y() - width)})); } painter.restore(); } // 使用示例 QPainter painter(canvas); QRectF rect = QRectF(start, QSize(width * 2, height * 2)); painter.setRenderHint(QPainter::Antialiasing); // 为了平滑效果 painter.drawRoundedRect(rect, 5, 5); // 可选地添加圆角 drawArrow(painter, rect.topLeft(), rect.bottomRight(), width); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值