不规则窗体的实现有两种方式:
一种是设置窗体的掩码图像;
另一种是设置窗体背景透明,然后重写其绘图函数,将背景图绘制上去。
第一种方式:
首先要准备两张图像,一张是要显示的图像,另一张是第一张图的掩码图像,黑色部分是你的窗体要显示的部分,如图:
具体实现的关键代码如下:
//IrregularForm1.h IrregularForm1::IrregularForm1(QWidget *parent) : QWidget(parent) { setWindowFlags(Qt::FramelessWindowHint);//设置窗体无边框 //设置背景 QPixmap pixmap(":/pic.png"); QPalette palette; palette.setBrush(backgroundRole(), QBrush(pixmap)); setPalette(palette); //设置窗体的掩码图像,抠除图像的白色区域实现不规则窗体 QBitmap bitmap(":/picmask.png"); setMask(bitmap); } |
运行效果不是特别完美,应该是我的掩码图像的问题,如图:
这种方式有一个问题,就是当你的图像特别不规则的时候,会有很明显的锯齿出现。之前做过一个卡通图像就出现这个问题,解决的办法是使用下面的第二种方法。
第二种方式:
只需要准备一张图片,透明部分将不会显示,支持半透明。我这里弄了一张背景透明,前景半透明的图像,如图:
具体实现的关键代码如下:
//IrregularForm2.cpp IrregularForm2::IrregularForm2(QWidget *parent) : QWidget(parent) { this->setWindowFlags(Qt::FramelessWindowHint);//设置窗体无边框 this->setAttribute(Qt::WA_TranslucentBackground);//设置背景透明 pic.load(":/IrregularPic.png");//加载图像 this->resize(pic.size()); } //重写绘图事件 void IrregularForm2::paintEvent(QPaintEvent *) { QPainter painter(this); painter.drawPixmap(0, 0, pic);//绘制图像 } |
效果截图:
说到这里,我们的不规则透明窗体虽然创建出来了,但是现在我们无法移动它了,现在我们就来实现左键拖动窗体的功能,首先要先声明两个变量,另外要重写三个事件,代码如下:
//IrregularForm1.h class IrregularForm1 : public QWidget { Q_OBJECT public: explicit IrregularForm1(QWidget *parent = 0); protected: QPoint oldPos; bool press; void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); }; |
关键的实现代码(press变量在构造函数中初始化为false):
//IrregularForm1.cpp void IrregularForm1::mousePressEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton) { oldPos = event->globalPos(); press = true; } } void IrregularForm1::mouseMoveEvent(QMouseEvent *event) { if (press) { this->move(this->pos() + event->globalPos() - oldPos); oldPos = event->globalPos(); } } void IrregularForm1::mouseReleaseEvent(QMouseEvent *event) { press = false; } |
这样就实现不规则窗体的移动功能了。
附件:
源码IrregularForm.zip
下载地址:
http://pan.baidu.com/share/link?shareid=135850&uk=3238766853