QPainterPath 不规则提示框(二)

前一篇讲过不规则提示框,但是提示框的方向是固定的,不能达到随意变换方向的效果,本接讲述可以动态变换方向的提示框

    先看效果图

图1

 

图2
图3

 

图4

    如上图1所示,上一篇文章的代码可以达到类似效果

    ​本片文章我只介绍变动部分,尽可能的做到详细吧

    ​​我先说原理,整个窗口包含两个布局器,水平布局和垂直布局,还有2个空间填充器,最后一个当然是显示消息的窗口,显示消息的窗口可以定制

图5

    整个窗口可以使用ui来做,也可以使用纯代码来控制,我使用了ui做布局部分,如图5,空间填充器是动态加入到布局中的​​,代码如下

  1 case TOPLEFT://箭头朝左上
  2 
  3 {
  4 
  5 ui->horizontalLayout->addSpacerItem(new QSpacerItem(size().width() / 8, 0
  6 
  7 , QSizePolicy::Maximum, QSizePolicy::Minimum));
  8 
  9 ui->horizontalLayout->addWidget(_p->messageWidget);//消息显示窗口
 10 
 11 ui->horizontalLayout->setStretch(0, 1);//设置空格和窗口长度比例
 12 
 13 ui->horizontalLayout->setStretch(1, 7);
 14 
 15 ui->verticalLayout->insertSpacerItem(0, new QSpacerItem(0, size().height() / 2
 16 
 17 , QSizePolicy::Minimum, QSizePolicy::Maximum));
 18 
 19 ui->verticalLayout->setStretch(0, 1);
 20 
 21 ui->verticalLayout->setStretch(1, 1);
 22 
 23 }
 24 
 25 break;
 26 
 27 case BOTTOMLEFT://箭头朝左下
 28 
 29 {
 30 
 31 ui->horizontalLayout->addSpacerItem(new QSpacerItem(size().width() / 8, 0
 32 
 33 , QSizePolicy::Maximum, QSizePolicy::Minimum));
 34 
 35 ui->horizontalLayout->addWidget(_p->messageWidget);
 36 
 37 ui->horizontalLayout->setStretch(0, 1);
 38 
 39 ui->horizontalLayout->setStretch(1, 7);
 40 
 41 ui->verticalLayout->addSpacerItem(new QSpacerItem(0, size().height() / 2
 42 
 43 , QSizePolicy::Minimum, QSizePolicy::Maximum));
 44 
 45 ui->verticalLayout->setStretch(0, 1);
 46 
 47 ui->verticalLayout->setStretch(1, 1);
 48 
 49 }
 50 
 51 break;
 52 
 53 case BOTTOMRIGHT://箭头朝 右下
 54 
 55 {
 56 
 57 ui->horizontalLayout->addWidget(_p->messageWidget);
 58 
 59 ui->horizontalLayout->addSpacerItem(new QSpacerItem(0, 0
 60 
 61 , QSizePolicy::Expanding, QSizePolicy::Minimum));
 62 
 63 ui->horizontalLayout->setStretch(0, 7);
 64 
 65 ui->horizontalLayout->setStretch(1, 1);
 66 
 67 ui->verticalLayout->addSpacerItem(new QSpacerItem(0, 0
 68 
 69 , QSizePolicy::Minimum, QSizePolicy::Expanding));
 70 
 71 ui->verticalLayout->setStretch(0, 1);
 72 
 73 ui->verticalLayout->setStretch(1, 1);
 74 
 75 }
 76 
 77 break;
 78 
 79 case TOPRIGHT://箭头朝右上
 80 
 81 {
 82 
 83 ui->horizontalLayout->addWidget(_p->messageWidget); 
 84 
 85 ui->horizontalLayout->addSpacerItem(new QSpacerItem(0, 0
 86 
 87 , QSizePolicy::Expanding, QSizePolicy::Minimum));
 88 
 89 ui->horizontalLayout->setStretch(0, 7);
 90 
 91 ui->horizontalLayout->setStretch(1, 1);
 92 
 93 ui->verticalLayout->insertSpacerItem(0, new QSpacerItem(0, 0
 94 
 95 , QSizePolicy::Minimum, QSizePolicy::Expanding));
 96 
 97 ui->verticalLayout->setStretch(0, 1);
 98 
 99 ui->verticalLayout->setStretch(1, 1);
100 
101 }
102 
103 break;
View Code

 

    整个窗口背景色透明后需要自己绘制窗口颜色,长款北京形状创建代码如下

  1 QPainterPath rectPath, triPath;
  2 
  3 switch (posStyle)
  4 
  5 {
  6 
  7 case 1:
  8 
  9 {
 10 
 11  rectPath.addRoundRect(QRect(size.width() / 8
 12 
 13  , size.height() / 2
 14 
 15  , size.width() / 8 * 7
 16 
 17  , size.height() / 2)
 18 
 19  , 10);
 20 
 21  triPath.moveTo(0, 0);
 22 
 23  triPath.lineTo(size.width() / 4, size.height() / 2);
 24 
 25  triPath.lineTo(size.width() / 8 * 3, size.height() / 2);
 26 
 27  triPath.lineTo(0, 0);
 28 
 29 }
 30 
 31 break;
 32 
 33 case 2:
 34 
 35 {
 36 
 37  rectPath.addRoundRect(QRect(0
 38 
 39  , size.height() / 2
 40 
 41  , size.width() / 8 * 7
 42 
 43  , size.height() / 2)
 44 
 45  , 10);
 46 
 47  triPath.moveTo(size.width(), 0);
 48 
 49  triPath.lineTo(size.width() / 4 * 3, size.height() / 2);
 50 
 51  triPath.lineTo(size.width() / 8 * 5, size.height() / 2);
 52 
 53  triPath.lineTo(size.width(), 0);
 54 
 55 }
 56 
 57 break;
 58 
 59 case 3:
 60 
 61 {
 62 
 63  rectPath.addRoundRect(QRect(0
 64 
 65  , 0
 66 
 67  , size.width() / 8 * 7
 68 
 69  , size.height() / 2)
 70 
 71  , 10);
 72 
 73  triPath.moveTo(size.width(), size.height());
 74 
 75  triPath.lineTo(size.width() / 4 * 3, size.height() / 2);
 76 
 77  triPath.lineTo(size.width() / 8 * 5, size.height() / 2);
 78 
 79  triPath.lineTo(size.width(), size.height());
 80 
 81 }
 82 
 83 break;
 84 
 85 case 4:
 86 
 87 {
 88 
 89  rectPath.addRoundRect(QRect(size.width() / 8
 90 
 91  , 0
 92 
 93  , size.width() / 8 * 7
 94 
 95  , size.height() / 2)
 96 
 97  , 10);
 98 
 99  triPath.moveTo(0, size.height());
100 
101  triPath.lineTo(size.width() / 4, size.height() / 2);
102 
103  triPath.lineTo(size.width() / 8 * 3, size.height() / 2);
104 
105  triPath.lineTo(0, size.height());
106 
107 }
108 
109 break;
110 
111 }
112 
113 rectPath.addPath(triPath);    //添加子闭合路径
114 
115 return rectPath;
View Code

    如此创建的提示窗口,在使用过程中需要用户根据箭头的指向 自己去移动窗口​,paintEvent函数没有变化

================================================​

    前边介绍的这两种不规则图形的绘制都是直接绘制在窗口上的,接下来我再介绍一种绘制不规则图形的方式​,只做大概讲述,具体实现代码我就不做过多的讲解 了,这种方式的原理就是贴图,我们把想要绘制的不规则图形先绘制到图片上,然后对图片做各种处理,比如旋转、镜像、平移等操作,然后在把图片绘制到窗口 上,这样做的好处是,这个不规则的形状可以随意变化,而不需要更改很多的代码。下面我写一下这种方式的伪代码

void 窗口重回函数()

{

    根据QImage构造QPainter对象或者指针

    构造如图1所示的不规则QPainterPath路径

    使用绘图对象把该路径绘制到QImage上​

    使用绘图对象把QImage绘制到窗口上​

}​

posted @ 2016-06-27 20:46  朝十晚八  阅读(1563)  评论(0编辑  收藏  举报

返回顶部