QT 三角气泡提示框(文字自适应、自定义三角位置)

一、效果图

在这里插入图片描述

二、实现代码
1.调用示例
void MainWindow::on_pushButton_clicked()
{
    BubbleTipsWidget *tips = new BubbleTipsWidget(this);
    
    QFont f;
    f.setFamily("Microsoft YaHei UI");
    f.setPixelSize(14);
    tips->setContentFont(f);
    
    tips->setBackColor(48, 49, 51, 240);
    tips->setDirect(DIRECT::DIRECT_TOP, 0.4);
    tips->setContent(tr("自定义气泡\n气泡大小根据文本大小自适应\n"
                        "设置气泡三角位置以及位置系数"),
                     QColor(Qt::white));
    tips->show();
}
2.BubbleTipsWidget.h
#ifndef _BUBBLETIPSWIDGET_H_
#define _BUBBLETIPSWIDGET_H_

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class BubbleTipsWidget; }
QT_END_NAMESPACE

// 三角形的高度
#define DEF_TRIANGLE_HEIGHT 5
// 透明宽度
#define TRANSPARENT_LENGTH 10
// 文字左边距
#define LEFT_MARGIN 10
// 文字上边距
#define TOP_MARGIN 10

enum class DIRECT {
    DIRECT_LEFT = 1,
    DIRECT_TOP,
    DIRECT_RIGHT,
    DIRECT_BOTTOM
};

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

    void setBackColor(int r, int g, int b, int a = 255);
    // 设置三角方向(左上右下),位置系数(宽度 * 系数)
    void setDirect(DIRECT direct = DIRECT::DIRECT_TOP, double size = 0.75);
    void setContentFont(QFont font = {});
    void setContent(const QString &content, QColor color = {});
    void setLeftTopMargin(int leftMargin = LEFT_MARGIN, int topMargin = TOP_MARGIN);

protected:
    void paintEvent(QPaintEvent *event);

private:
    Ui::BubbleTipsWidget *ui;
    QColor          m_backColor  {255, 0, 255, 255};
    DIRECT          m_direct;

    double          m_posSize    {0.75};
    int             m_leftMargin {LEFT_MARGIN};
    int             m_topMargin  {TOP_MARGIN};
};
#endif // _BUBBLETIPSWIDGET_H_

3.BubbleTipsWidget.cpp
#include "BubbleTipsWidget.h"
#include "ui_BubbleTipsWidget.h"
#include <QPainter>

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

    setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
    setAttribute(Qt::WA_TranslucentBackground);

    setBackColor(0, 0, 0);
    setDirect(DIRECT::DIRECT_BOTTOM, 0.75);

    QFont f;
    f.setFamily("Microsoft YaHei UI");
    f.setPixelSize(14);
    setContentFont(f);
    setContent("I am a default text");

    setLeftTopMargin();
}

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

void BubbleTipsWidget::setBackColor(int r, int g, int b, int a)
{
    m_backColor = QColor(r, g, b, a);
}

void BubbleTipsWidget::setDirect(DIRECT direct, double size)
{
    m_direct = direct;
    m_posSize = size;
}

void BubbleTipsWidget::setContentFont(QFont font)
{
    ui->label->setFont(font);
}

void BubbleTipsWidget::setContent(const QString &content, QColor color)
{
    ui->label->setText(content);
    ui->label->setStyleSheet(QString("color: rgb(%1, %2, %3)")
                             .arg(color.red())
                             .arg(color.green())
                             .arg(color.blue()));
}

void BubbleTipsWidget::setLeftTopMargin(int leftMargin, int topMargin)
{
    m_leftMargin = leftMargin;
    m_topMargin = topMargin;
    this->setContentsMargins(m_leftMargin + TRANSPARENT_LENGTH,
                             m_topMargin + TRANSPARENT_LENGTH,
                             m_leftMargin + TRANSPARENT_LENGTH,
                             m_topMargin + TRANSPARENT_LENGTH);
}

void BubbleTipsWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing);


    painter.setPen(Qt::NoPen);
    painter.setBrush(m_backColor);

    //相对于当前布局的起点坐标
    painter.drawRoundedRect(TRANSPARENT_LENGTH, TRANSPARENT_LENGTH,
                            width() - TRANSPARENT_LENGTH * 2,
                            height() - TRANSPARENT_LENGTH * 2, 4, 4);
    QPointF points[3];

    switch (m_direct) {
    case DIRECT::DIRECT_LEFT: {
        points[0] = QPointF(TRANSPARENT_LENGTH,
                            height() * m_posSize - DEF_TRIANGLE_HEIGHT);
        points[1] = QPointF(TRANSPARENT_LENGTH - DEF_TRIANGLE_HEIGHT,
                            height() * m_posSize);
        points[2] = QPointF(TRANSPARENT_LENGTH,
                            height() * m_posSize + DEF_TRIANGLE_HEIGHT);
        break;
    }

    case DIRECT::DIRECT_TOP: {
        points[0] = QPointF(width() * m_posSize - DEF_TRIANGLE_HEIGHT,
                            TRANSPARENT_LENGTH);
        points[1] = QPointF(width() * m_posSize,
                            TRANSPARENT_LENGTH - DEF_TRIANGLE_HEIGHT);
        points[2] = QPointF(width() * m_posSize + DEF_TRIANGLE_HEIGHT,
                            TRANSPARENT_LENGTH);
        break;
    }

    case DIRECT::DIRECT_RIGHT: {
        points[0] = QPointF(width() - TRANSPARENT_LENGTH,
                            height() * m_posSize - DEF_TRIANGLE_HEIGHT);
        points[1] = QPointF(width() - DEF_TRIANGLE_HEIGHT, height() * m_posSize);
        points[2] = QPointF(width() - TRANSPARENT_LENGTH,
                            height() * m_posSize + DEF_TRIANGLE_HEIGHT);
        break;
    }

    case DIRECT::DIRECT_BOTTOM: {
        points[0] = QPointF(width() * m_posSize - DEF_TRIANGLE_HEIGHT,
                            height() - TRANSPARENT_LENGTH);
        points[1] = QPointF(width() * m_posSize, height() - DEF_TRIANGLE_HEIGHT);
        points[2] = QPointF(width() * m_posSize + DEF_TRIANGLE_HEIGHT,
                            height() - TRANSPARENT_LENGTH);
        break;
    }

    default:
        break;
    }

    painter.drawPolygon(points, 3);
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值