前一篇讲过不规则提示框,但是提示框的方向是固定的,不能达到随意变换方向的效果,本接讲述可以动态变换方向的提示框
先看效果图
如上图1所示,上一篇文章的代码可以达到类似效果
本片文章我只介绍变动部分,尽可能的做到详细吧
我先说原理,整个窗口包含两个布局器,水平布局和垂直布局,还有2个空间填充器,最后一个当然是显示消息的窗口,显示消息的窗口可以定制
整个窗口可以使用ui来做,也可以使用纯代码来控制,我使用了ui做布局部分,如图5,空间填充器是动态加入到布局中的,代码如下
case TOPLEFT://箭头朝左上 { ui->horizontalLayout->addSpacerItem(new QSpacerItem(size().width() / , , QSizePolicy::Maximum, QSizePolicy::Minimum)); ui->horizontalLayout->addWidget(_p->messageWidget);//消息显示窗口 ui->horizontalLayout->setStretch(, );//设置空格和窗口长度比例 ui->horizontalLayout->setStretch(, ); ui->verticalLayout->insertSpacerItem(, new QSpacerItem(, size().height() / , QSizePolicy::Minimum, QSizePolicy::Maximum)); ui->verticalLayout->setStretch(, ); ui->verticalLayout->setStretch(, ); } break; case BOTTOMLEFT://箭头朝左下 { ui->horizontalLayout->addSpacerItem(new QSpacerItem(size().width() / , , QSizePolicy::Maximum, QSizePolicy::Minimum)); ui->horizontalLayout->addWidget(_p->messageWidget); ui->horizontalLayout->setStretch(, ); ui->horizontalLayout->setStretch(, ); ui->verticalLayout->addSpacerItem(new QSpacerItem(, size().height() / , QSizePolicy::Minimum, QSizePolicy::Maximum)); ui->verticalLayout->setStretch(, ); ui->verticalLayout->setStretch(, ); } break; case BOTTOMRIGHT://箭头朝 右下 { ui->horizontalLayout->addWidget(_p->messageWidget); ui->horizontalLayout->addSpacerItem(new QSpacerItem(, , QSizePolicy::Expanding, QSizePolicy::Minimum)); ui->horizontalLayout->setStretch(, ); ui->horizontalLayout->setStretch(, ); ui->verticalLayout->addSpacerItem(new QSpacerItem(, , QSizePolicy::Minimum, QSizePolicy::Expanding)); ui->verticalLayout->setStretch(, ); ui->verticalLayout->setStretch(, ); } break; case TOPRIGHT://箭头朝右上 { ui->horizontalLayout->addWidget(_p->messageWidget); ui->horizontalLayout->addSpacerItem(new QSpacerItem(, , QSizePolicy::Expanding, QSizePolicy::Minimum)); ui->horizontalLayout->setStretch(, ); ui->horizontalLayout->setStretch(, ); ui->verticalLayout->insertSpacerItem(, new QSpacerItem(, , QSizePolicy::Minimum, QSizePolicy::Expanding)); ui->verticalLayout->setStretch(, ); ui->verticalLayout->setStretch(, ); } break;
整个窗口背景色透明后需要自己绘制窗口颜色,长款北京形状创建代码如下
QPainterPath rectPath, triPath; switch (posStyle) { case : { rectPath.addRoundRect(QRect(size.width() / , size.height() / , size.width() / * , size.height() / ) , ); triPath.moveTo(, ); triPath.lineTo(size.width() / , size.height() / ); triPath.lineTo(size.width() / * , size.height() / ); triPath.lineTo(, ); } break; case : { rectPath.addRoundRect(QRect( , size.height() / , size.width() / * , size.height() / ) , ); triPath.moveTo(size.width(), ); triPath.lineTo(size.width() / * , size.height() / ); triPath.lineTo(size.width() / * , size.height() / ); triPath.lineTo(size.width(), ); } break; case : { rectPath.addRoundRect(QRect( , , size.width() / * , size.height() / ) , ); triPath.moveTo(size.width(), size.height()); triPath.lineTo(size.width() / * , size.height() / ); triPath.lineTo(size.width() / * , size.height() / ); triPath.lineTo(size.width(), size.height()); } break; case : { rectPath.addRoundRect(QRect(size.width() / , , size.width() / * , size.height() / ) , ); triPath.moveTo(, size.height()); triPath.lineTo(size.width() / , size.height() / ); triPath.lineTo(size.width() / * , size.height() / ); triPath.lineTo(, size.height()); } break; } rectPath.addPath(triPath); //添加子闭合路径 return rectPath;
如此创建的提示窗口,在使用过程中需要用户根据箭头的指向 自己去移动窗口,paintEvent函数没有变化
================================================
前边介绍的这两种不规则图形的绘制都是直接绘制在窗口上的,接下来我再介绍一种绘制不规则图形的方式,只做大概讲述,具体实现代码我就不做过多的讲解 了,这种方式的原理就是贴图,我们把想要绘制的不规则图形先绘制到图片上,然后对图片做各种处理,比如旋转、镜像、平移等操作,然后在把图片绘制到窗口 上,这样做的好处是,这个不规则的形状可以随意变化,而不需要更改很多的代码。下面我写一下这种方式的伪代码
void 窗口重回函数()
{
根据QImage构造QPainter对象或者指针
构造如图1所示的不规则QPainterPath路径
使用绘图对象把该路径绘制到QImage上
使用绘图对象把QImage绘制到窗口上
}