zoukankan      html  css  js  c++  java
  • 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绘制到窗口上​

    }​

  • 相关阅读:
    DriveInfo 类 提供对有关驱动器的信息的访问
    遍历数组 例子
    怎么判断点击dataGridView1的是第几列
    无法加载协定为“ServiceReference1.LanguageService”的终结点配置部分,因为找到了该协定的多个终结点配置。请按名称指示首选的终结点配置部分。
    c#面试题及答案(一)
    SQL杂谈 ,有你想要的...
    TextView和Button的学习
    GitHub的学习和使用
    App的布局管理
    EditText制作简单的登录界面
  • 原文地址:https://www.cnblogs.com/swarmbees/p/5621514.html
Copyright © 2011-2022 走看看