- 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