Qt绘图与图形视图之绘制带三角形箭头的窗口的简单介绍

往期回顾

Qt绘图与图形视图之场景、视图架构的简单介绍-CSDN博客

Qt绘图与图形视图之基本图元绘制的简单介绍-CSDN博客

Qt绘图与图形视图之自定义图元实现拖拽、拉伸、旋转功能-CSDN博客

 Qt绘图与图形视图之绘制带三角形箭头的窗口的简单介绍

一、最终效果

点击pushbutton按钮,弹出一个带三角形的对话框,其三角形正好就在按钮正中心下方

二、设计思路

 需要考虑两个问题:

1、这个对话框怎么画,才能够有这种效果,矩形上冒出个小三角形;

2、如何精准找到这个位置,让其准确显示在按钮下方;

3、对话框的设计

三、具体设计实现

1、对话框怎么画

这里由于是点击按钮弹出,所以对话框是继承自对话框类Dialog,主要抓住几个关键点,三角形的起始位置和底边长、高度。

1.1、setTriangleInfo函数

setTriangleInfo函数用于设置小三角形的起始位置、宽度和高度,以便在对话框绘制时使用。

其中涉及到一个explicit关键字

在C++中,explicit关键字用于声明一个构造函数为显式构造函数。当一个构造函数被声明为explicit时,它将禁止隐式转换和复制初始化。这意味着在使用该构造函数创建对象时,必须显式调用构造函数,而不能通过隐式转换或复制初始化来创建对象。这样做可以避免一些意外的类型转换,提高代码的可读性和安全性。 

/*

带三角形箭头的对话框

*/

#ifndef TRIANGLEDIALOG_H
#define TRIANGLEDIALOG_H

#include <QDialog>

class TriangleDialog : public QDialog
{
    Q_OBJECT
public:
    explicit TriangleDialog(int fixedW, int fixedH, QWidget *parent = nullptr);

    // 设置小三角行的起始位置、宽、高
    void setTriangleInfo(int startX, int width, int height);

protected:
    void paintEvent(QPaintEvent *e);

private:
    // 小三角形的起始位置
    int m_startX;

    // 小三角形的宽度
    int m_triangleWidth;

    // 小三角形的高度
    int m_triangleHeight;
};

#endif // TRIANGLEDIALOG_H

1.2、对关键参数直接宏定义

#define SHADOW_WIDTH    15                 // 窗口阴影宽度
#define TRIANGLE_WIDTH  15                 // 小三角行的宽度
#define TRIANGLE_HEIGHT 10                 // 小三角行的高度
#define BORDER_RADIUS   5                  // 窗口圆角

1.3、设置对话框的窗口标志 

 setWindowFlags(Qt::FramelessWindowHint | Qt::Popup | Qt::NoDropShadowWindowHint);
    setAttribute(Qt::WA_TranslucentBackground);  // 设置透明窗口, 为窗口阴影和圆角做准备

几个注意点:

Qt::FramelessWindowHint: 表示对话框没有窗口边框和标题栏,即无边框窗口。
Qt::Popup: 表示对话框是一个弹出式窗口,通常用于弹出式菜单或提示框。
Qt::NoDropShadowWindowHint: 表示对话框不显示窗口阴影效果。

1.4、设置布局的四周边距

 参数是左上右下,除了上需要加上三角形的高之外,其他都一样的大小,直接用15

 pVlay->setContentsMargins(SHADOW_WIDTH, SHADOW_WIDTH + TRIANGLE_HEIGHT, SHADOW_WIDTH, SHADOW_WIDTH);

1.5、设置阴影效果 

setGraphicsEffect(QGraphicsEffect *effect):

这个方法用于为一个窗口部件设置图形效果。可以通过传入一个QGraphicsEffect对象来实现各种特效,比如阴影、模糊等。这个方法可以让窗口部件呈现出更加生动和美观的效果。

    // 设置阴影边框
    auto shadowEffect = new QGraphicsDropShadowEffect(this);
    shadowEffect->setOffset(0, 0);
    shadowEffect->setColor(Qt::red);
    shadowEffect->setBlurRadius(SHADOW_WIDTH);
    //setGraphicsEffect(QGraphicsEffect *effect):用于为一个窗口部件设置图形效果
    this->setGraphicsEffect(shadowEffect);

 1.6、重写paintEvent方法

 1.6.1、代码示例
void TriangleDialog::paintEvent(QPaintEvent *e)
{
    QPainter painter(this);
    //setRenderHint(QPainter::RenderHint hint, bool on = true):用于设置绘图时的渲染提示
    //hint参数表示要设置的渲染提示,比如抗锯齿、文本抗锯齿等。on参数表示是否开启这个渲染提示
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(Qt::NoPen); //将画笔设置为无边框
    painter.setBrush(QColor(55, 55, 55)); //设置画刷颜色为灰色

    // 小三角区域,这里是等腰三角形
    //小三角形的三个点的坐标,注意不要忘记窗口边距就行
    QPolygon trianglePolygon;
    trianglePolygon << QPoint(m_startX, m_triangleHeight + SHADOW_WIDTH);
    trianglePolygon << QPoint(m_startX + m_triangleWidth / 2, SHADOW_WIDTH);
    trianglePolygon << QPoint(m_startX + m_triangleWidth, m_triangleHeight + SHADOW_WIDTH);

    QPainterPath drawPath; //用于定义整个绘制路径

    //调用 drawPath.addRoundedRect 方法添加一个带有圆角的矩形路径,用于绘制矩形框的主体部分。
    // 圆角的半径由 BORDER_RADIUS 定义
    //addRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius):用于在绘图路径中添加一个带有圆角的矩形
    drawPath.addRoundedRect(QRect(SHADOW_WIDTH, SHADOW_WIDTH + m_triangleHeight,
                                  this->width() - SHADOW_WIDTH * 2, this->height() - SHADOW_WIDTH * 2 - m_triangleHeight),
                            BORDER_RADIUS, BORDER_RADIUS);


    // 矩形路径加上三角形
    //addPolygon(const QPolygonF &polygon):用于在绘图路径中添加一个多边形
    //polygon参数表示要添加的多边形的顶点坐标
    drawPath.addPolygon(trianglePolygon);

    // 绘制整个路径
    painter.drawPath(drawPath);
}
1.6.2、代码执行思路 

其实是很简单的,我们只需要指出小三角形的三个点位置,然后添加进去拿给painter.drawPath,他自己会画好

具体思路:

(1)首先创建了一个 QPainter 对象 painter,将画笔设置为无边框, 画刷颜色设置为灰色
(2)然后创建了一个QPolygon对象trianglePolygon,用于定义小三角形的顶点坐标。
(3)接着创建了一个 QPainterPath 对象 drawPath,用于定义整个绘制路径。
(4)调用drawPath.addRoundedRect方法添加一个带有圆角的矩形路径,用于绘制矩形框的主体部分。
(5)圆角的半径由 BORDER_RADIUS 定义。
(6)调用 drawPath.addPolygon 方法将小三角形的路径添加到整个绘制路径中。
(7)最后调用 painter.drawPath(drawPath) 方法来绘制整个路径,包括带有圆角的矩形和小三角形。

1.6.3、QPolygon类 

QPolygon是Qt中用于表示多边形的类,它可以用来表示一个多边形的顶点坐标。它提供了方便的接口来操作多边形,可以用于绘制各种形状的图形,进行碰撞检测等操作。

1.6.3.1、构造函数:
QPolygon(): 创建一个空的多边形。
QPolygon(const QPolygon &other): 使用另一个 QPolygon 对象来初始化新的多边形。
QPolygon(const QVector<QPoint> &points): 使用给定的点集合来初始化新的多边形。
1.6.3.2、成员函数:
void << (const QPoint &point): 向多边形中添加一个顶点。
int size() const: 返回多边形中顶点的个数。
QPoint at(int i) const: 返回多边形中第 i 个顶点的坐标。
void setPoint(int i, const QPoint &point): 设置多边形中第 i 个顶点的坐标。
bool containsPoint(const QPoint &point, Qt::FillRule fillRule = Qt::OddEvenFill) const: 检查给定的点是否在多边形内部。
QRect boundingRect() const: 返回包围多边形的最小矩形区域。

1.6.3.3、使用场景:

绘制不规则图形: 通过定义多边形的顶点坐标,可以绘制各种不规则形状的图形。
碰撞检测: 可以使用 containsPoint 方法来检查一个点是否在多边形内部,用于碰撞检测等应用场景。
图形处理: 在图形处理和绘图应用中,多边形常用于定义复杂的图形形状。
 1.6.4、几个难懂的方法

 1.6.4.1、

setRenderHint(QPainter::RenderHint hint, bool on = true):

这个方法用于设置绘图时的渲染提示。hint参数表示要设置的渲染提示,比如抗锯齿、文本抗锯齿等。on参数表示是否开启这个渲染提示。通过设置不同的渲染提示,可以优化绘图的效果和性能。 

 1.6.4.2、 

addRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius):

这个方法用于在绘图路径中添加一个带有圆角的矩形。rect参数表示矩形的位置和大小,xRadius和yRadius参数表示矩形的水平和垂直方向的圆角半径。这个方法常用于绘制带有圆角的界面元素,比如圆角按钮、对话框等。 

 1.6.4.3、 

addPolygon(const QPolygonF &polygon):

 这个方法用于在绘图路径中添加一个多边形。polygon参数表示要添加的多边形的顶点坐标。通过添加多边形,可以在绘图中绘制各种复杂的形状。

2、如何准确找到对话框弹出的位置 

看这个之前要想清楚一个问题,这个对话框弹出的位置不是相对于widget窗口而言的,不能以窗口的(0,0)到对话框的位置大小来当作其坐标。

2.1、思路

重点在于,要找到三角形所在对话框的左上角位置,通过画图思考:

2.1.1、X位置

其实想通了很简单,x就是按钮的左上角x+按钮宽度一半-三角形起始点的x-三角形底边一半的宽

int x = p1.x() + rect1.width() / 2 - triangle_start_x - 20 / 2;

如果想不通,就简单化,从最终效果来看,按钮的x本来和对话框x就是一样大的(这个画的图有问题,看最终效果图),但是要减去一个窗口边距

 所以直接:int x = p1.x() - 15;

结果也是正确的 

2.1.2、Y位置 

这个就更好想了,按钮的起始点y+按钮本身高度-窗口边距15

多减一是因为不想贴合太紧

int y = p1.y() + rect1.height() + 1 - 15;

3、对话框设计 

 这个我们应该是已经很熟悉了,没啥好说的,大家看看就行

#include "userinfowidget.h"
#include "ui_userinfowidget.h"

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

    setFixedSize(this->width(), this->height());

    setAttribute(Qt::WA_StyledBackground);
    QString qss = "QLabel{font-family:Microsoft YaHei; font-size:18px; color:#ffffff; background-color:#363636;}";

    ui->label_UserImage->setText("");
    QPixmap pmp1(":/resources/user_image.png");
    pmp1.scaled(ui->label_UserImage->size(), Qt::KeepAspectRatio);
    ui->label_UserImage->setScaledContents(true);
    ui->label_UserImage->setPixmap(pmp1);

    ui->label_UserName->setText(u8"没有做完的梦最痛");
    ui->label_UserName->setStyleSheet(qss);

    ui->label_VipInfo->setText("");
    QPixmap pmp2(":/resources/vipinfo.png");
    pmp2.scaled(ui->label_VipInfo->size(), Qt::KeepAspectRatio);
    ui->label_VipInfo->setScaledContents(true);
    ui->label_VipInfo->setPixmap(pmp2);
}

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

以上就是Qt里实现绘制带三角形箭头的窗口的简单介绍。

都看到这里了,点个赞再走呗朋友~

加油吧,预祝大家变得更强!

相关推荐

  1. Qt绘图图形视图Graphics View坐标系简单介绍

    2024-05-03 03:42:03       13 阅读
  2. Qt图表图形绘制介绍

    2024-05-03 03:42:03       6 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-03 03:42:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-03 03:42:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-03 03:42:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-03 03:42:03       20 阅读

热门阅读

  1. Django知识点总结

    2024-05-03 03:42:03       15 阅读
  2. React框架是什么

    2024-05-03 03:42:03       14 阅读
  3. “一万年太久,只争朝夕”

    2024-05-03 03:42:03       16 阅读
  4. C# Solidworks二次开发:枚举应用实战(第九讲)

    2024-05-03 03:42:03       12 阅读
  5. C++_课堂笔记_构造与析构

    2024-05-03 03:42:03       12 阅读
  6. js判定-矩形内是否包含指定点

    2024-05-03 03:42:03       15 阅读
  7. 知识图谱的理论, 相关工具和实际应用

    2024-05-03 03:42:03       10 阅读
  8. SpringBoot+vue实现登录功能

    2024-05-03 03:42:03       12 阅读
  9. YOLOv8 是一个相对较新的目标检测算法

    2024-05-03 03:42:03       12 阅读