常见的窗体通常是各种方形的对话框,如前面实例中实现的所有对话框都是这样的。但有时也会需要用到非方形的窗体,如圆形,椭圆形甚至是不规则形状的对话框。
本实例即实现了一个对PNG图形外沿为形状的不规则形状对话框,如下图所示。
在图中所示的哆拉A梦即为一个不规则窗体,实例在不规则窗体中绘制了作为窗体形状的PNG图片,也可在不规则窗体上放置按钮等控件,可以通过鼠标左键拖动窗体,鼠标右键关闭窗体。
具体实现代码如下:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys
class ShapeWidget(QWidget):
def __init__(self,parent=None):
super(ShapeWidget,self).__init__(parent)
pix=QPixmap("image/21.png","0",Qt.AvoidDither|Qt.ThresholdDither|Qt.ThresholdAlphaDither)
self.resize(pix.size())
self.setMask(pix.mask())
self.dragPosition=None
def mousePressEvent(self,event):
if event.button()==Qt.LeftButton:
self.dragPosition=event.globalPos()-self.frameGeometry().topLeft()
event.accept()
if event.button()==Qt.RightButton:
self.close()
def mouseMoveEvent(self,event):
if event.buttons() & Qt.LeftButton:
self.move(event.globalPos()-self.dragPosition)
event.accept()
def paintEvent(self,event):
painter=QPainter(self)
painter.drawPixmap(0,0,QPixmap("image/21.png"))
app=QApplication(sys.argv)
form=ShapeWidget()
form.show()
app.exec_()
ShapeWidget即为此不规则窗体类,继承自QWidget类。在类中重定义的鼠标事件mousePressEvent(),mouseMoveEvent()以及绘制函数paintEvent(),使不规则窗体能用鼠标随意拖动。
第9行新建一个QPixmap对象。
第10行重设主窗体的尺寸为所读取的图片的大小。
第11行的setMask()命令是实现不规则窗体的关键,setMask()的作用是为调用它的控件增加一个遮罩,遮住所选区域以外的部分使之看起来是透明的,它的参数可为一个QBitmap对象或一个QRegion对象,此处调用QPixmap的mask()函数获得图片自身的遮罩,为一个QBitmap对象。实例中使用的是png格式的图片,它的透明部分实际上即是一个遮罩。
重定义鼠标按下响应函数mousePressEvent(QMouseEvent)和鼠标移动响应函数mouseMoveEvent(QMouseEvent),使不规则窗体能响应鼠标事件,随意拖动。
在mousePressEvent函数中,首先判断按下的是否为鼠标左键,若是则保存当前鼠标点所在的位置相对于窗体左上角的偏移值dragPosition,如果按下鼠标右键,则关闭窗体。
此处的frameGeometry().topLeft()仍然表示整个窗体的左上角,而并不是所见的不规则窗体的左上角。
在mouseMoveEvent函数中,首先判断当前鼠标状态,调用event.buttons()返回鼠标的状态,若为左侧按钮则调用QWidget的move()函数把窗体移动至鼠标当前点,由于move()函数的参数指的是窗体的左上角的位置,因此要用鼠标当前点的位置减去相对窗体左上角的偏移值dragPosition。
ShapeWidget的重画函数主要完成在窗体上绘制图片的工作,此处为方便显示在窗体上绘制的即是用来确定窗体外形的PNG图片。
注:本文基本上是经过改编的《Linux窗口程序设计--Qt4精彩实例分析》一书的PyQt4 for windows版本
http://blog.youkuaiyun.com/chumpklutz/article/details/6099125