- A+
 
效果
源码
trianglepopupwidget.h文件
- #ifndef TRIANGLEPOPUPWIDGET_H
 - #define TRIANGLEPOPUPWIDGET_H
 - #include <QWidget>
 - #include <QPoint>
 - #include <QRect>
 - #include <QSize>
 - class TrianglePopupWidget: public QWidget
 - {
 - Q_OBJECT
 - public:
 - TrianglePopupWidget(QPoint triangleStartPosition
 - ,QSize rectSize,QRect windowGeometry=QRect(0,0,1920,1080),QWidget *parent = 0);
 - ~TrianglePopupWidget();
 - // 设置中间区域widget;
 - void addCenterWidget(QWidget* widget);
 - void setTriangleSize(const QSize &triangleSize);
 - QRect windowGeometry() const;
 - void setWindowGeometry(const QRect &windowGeometry);
 - void setMargins(int left, int top, int right, int bottom);
 - QColor backgroundColor() const;
 - void setBackgroundColor(const QColor &backgroundColor);
 - protected:
 - void paintEvent(QPaintEvent *);
 - private:
 - // 小三角起始位置;
 - QPoint m_triangleStartPosition;
 - // 小三角的size;
 - QSize m_triangleSize;
 - // 是否绘制阴影
 - int m_isDrawShadowOrNot;
 - // 内容矩形的长宽
 - QSize m_rectSize;
 - QColor m_backgroundColor;
 - QLayout* m_layout;
 - //qmaindow大小
 - QRect m_windowGeometry;
 - void calculateGeometry();
 - };
 - #endif // TRIANGLEPOPUPWIDGET_H
 
trianglepopupwidget.cpp文件
- #include "trianglepopupwidget.h"
 - #include <QHBoxLayout>
 - #include <QPainter>
 - #include <QGraphicsDropShadowEffect>
 - #define SHADOW_WIDTH 0 // 窗口阴影宽度;
 - #define TRIANGLE_WIDTH 15 // 小三角的宽度;
 - #define TRIANGLE_HEIGHT 10 // 小三角的高度;
 - #define BORDER_RADIUS 5 // 窗口边角的弧度;
 - TrianglePopupWidget::TrianglePopupWidget(QPoint triangleStartPosition
 - ,QSize rectSize
 - ,QRect windowGeometry
 - ,QWidget *parent)
 - : QWidget(parent)
 - , m_rectSize(rectSize)
 - , m_triangleStartPosition(triangleStartPosition)
 - , m_isDrawShadowOrNot(false)
 - , m_windowGeometry(windowGeometry)
 - , m_layout(NULL)
 - {
 - setWindowFlags(Qt::FramelessWindowHint);
 - setAttribute(Qt::WA_TranslucentBackground);
 - m_triangleSize = QSize(TRIANGLE_WIDTH,TRIANGLE_HEIGHT);
 - m_backgroundColor = QColor(255,255,255);
 - // 设置阴影边框;
 - if(m_isDrawShadowOrNot)
 - {
 - QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect(this);
 - shadowEffect->setOffset(0, 0);
 - shadowEffect->setColor(Qt::gray);
 - shadowEffect->setBlurRadius(SHADOW_WIDTH);
 - this->setGraphicsEffect(shadowEffect);
 - }
 - calculateGeometry();
 - }
 - TrianglePopupWidget::~TrianglePopupWidget()
 - {
 - }
 - //计算整个widget的Geometry
 - void TrianglePopupWidget::calculateGeometry()
 - {
 - int x=0;
 - int y=0;
 - int width = m_rectSize.width();
 - int height = m_rectSize.height()+m_triangleSize.height();
 - int standard_startX = m_triangleStartPosition.x()-m_rectSize.width()/2;
 - int standard_startY = m_triangleStartPosition.y()-m_triangleSize.height()-m_rectSize.height();
 - int standard_endX = m_triangleStartPosition.x()-m_rectSize.width()/2+width;
 - int standard_endY = m_triangleStartPosition.y()-m_triangleSize.height()-m_rectSize.height() + height;
 - if(standard_startX<m_windowGeometry.x()+10)
 - {
 - standard_startX = m_windowGeometry.x()+10;
 - }
 - if(standard_endX>m_windowGeometry.y()+m_windowGeometry.width()-10)
 - {
 - standard_startX = standard_startX - (standard_endX-(m_windowGeometry.y()+m_windowGeometry.width()-10));
 - }
 - //微调
 - if(m_triangleStartPosition.x()<standard_startX+m_triangleSize.width()/2+BORDER_RADIUS)
 - {
 - standard_startX = m_triangleStartPosition.x() - BORDER_RADIUS - m_triangleSize.width()/2;
 - }
 - //微调
 - if(m_triangleStartPosition.x()>standard_startX+width-m_triangleSize.width()/2-BORDER_RADIUS )
 - {
 - standard_startX = standard_startX+m_triangleSize.width()/2+BORDER_RADIUS ;
 - }
 - x = standard_startX;
 - y = standard_startY;
 - this->setGeometry(x,y,width,height);
 - }
 - void TrianglePopupWidget::addCenterWidget(QWidget* widget)
 - {
 - if(NULL == m_layout)
 - {
 - m_layout = new QHBoxLayout(this);
 - m_layout->setSpacing(10);
 - m_layout->setContentsMargins(10,10,10,10+TRIANGLE_HEIGHT);
 - }
 - m_layout->addWidget(widget);
 - }
 - void TrianglePopupWidget::setMargins(int left,int top,int right,int bottom)
 - {
 - if(NULL != m_layout)
 - {
 - m_layout->setContentsMargins(left,top,right,bottom+TRIANGLE_HEIGHT);
 - }
 - }
 - void TrianglePopupWidget::paintEvent(QPaintEvent *)
 - {
 - QPainter painter(this);
 - painter.setRenderHint(QPainter::Antialiasing, true);
 - painter.setPen(Qt::NoPen);
 - painter.setBrush(m_backgroundColor);
 - // 小三角区域
 - QPolygon trianglePolygon;
 - QPoint pt_triStartPosRelaThis(m_triangleStartPosition.x()-geometry().x(),
 - m_triangleStartPosition.y()-geometry().y());
 - // int x1=m_triangleStartPosition.x()-geometry().x();
 - // int y1=m_triangleStartPosition.y()-geometry().y();
 - // int x2=pt_triStartPosRelaThis.x() + m_triangleSize.width() / 2;
 - // int y2=pt_triStartPosRelaThis.y()-m_triangleSize.height();
 - // int x3=pt_triStartPosRelaThis.x() - m_triangleSize.width() / 2;
 - // int y3=pt_triStartPosRelaThis.y()-m_triangleSize.height();
 - trianglePolygon << pt_triStartPosRelaThis;
 - trianglePolygon << QPoint(pt_triStartPosRelaThis.x() + m_triangleSize.width() / 2
 - , pt_triStartPosRelaThis.y()-m_triangleSize.height());
 - trianglePolygon << QPoint(pt_triStartPosRelaThis.x() - m_triangleSize.width() / 2
 - , pt_triStartPosRelaThis.y()-m_triangleSize.height());
 - QPainterPath drawPath;
 - //矩形区域
 - drawPath.addRoundedRect(QRect(0,0,m_rectSize.width(),m_rectSize.height()),BORDER_RADIUS,BORDER_RADIUS);
 - // Rect + Triangle;
 - drawPath.addPolygon(trianglePolygon);
 - painter.drawPath(drawPath);
 - }
 - QColor TrianglePopupWidget::backgroundColor() const
 - {
 - return m_backgroundColor;
 - }
 - void TrianglePopupWidget::setBackgroundColor(const QColor &backgroundColor)
 - {
 - m_backgroundColor = backgroundColor;
 - }
 - QRect TrianglePopupWidget::windowGeometry() const
 - {
 - return m_windowGeometry;
 - }
 - void TrianglePopupWidget::setWindowGeometry(const QRect &windowGeometry)
 - {
 - m_windowGeometry = windowGeometry;
 - }
 - void TrianglePopupWidget::setTriangleSize(const QSize &triangleSize)
 - {
 - m_triangleSize = triangleSize;
 - }
 
使用方法
- TrianglePopupWidget* w = new TrianglePopupWidget(
 - pt
 - ,QSize(400,100)
 - ,QRect(0,0,800,600)
 - ,this);
 - QLabel* textLabel = new QLabel;
 - textLabel->setAlignment(Qt::AlignCenter);
 - textLabel->setText("ArrowWidget");
 - textLabel->setStyleSheet("background-color:red");
 - w->addCenterWidget(textLabel);
 - QLabel* textLabel2 = new QLabel;
 - textLabel2->setAlignment(Qt::AlignCenter);
 - textLabel2->setText("DDDDA");
 - textLabel2->setStyleSheet("background-color:green");
 - w->addCenterWidget(textLabel2);
 - QLabel* textLabel3 = new QLabel;
 - textLabel3->setAlignment(Qt::AlignCenter);
 - textLabel3->setText("bbbb");
 - textLabel3->setStyleSheet("background-color:yellow");
 - w->addCenterWidget(textLabel3);
 - QColor clr(0,0,255);
 - w->setBackgroundColor(clr);
 - w->show();
 
代码下载地址
https://github.com/2273629531/TrianglePopupWidget



				