PyQt一般实现的窗体就是当前操作系统原生窗体的样式,ubuntu下的窗体还不错,window下的就难看了,虽然平时应用程序关心的往往是业务和功能,但是偶尔我们也需要制作一些个性的窗体样式,如QQ、360、千千静听等,这种漂亮个性的窗体,很能吸引大众的眼球。
实现不规则窗体,我采用继承QWidget这个部件基类并重绘之,有几个知识点:
- 重写paintEvent事件,可以绘制窗体的背景图片
- 调用setMask方法设置窗体的遮罩层,可以个性化窗体,掩码图片黑色部分即是要显示的,白色即是要隐藏的
- 要理解QPixmap和QBitmap的区别,QBitmap是QPixmap的子类别,提供单色图像
from PyQt4.QtGui import * from PyQt4.QtCore import * class MyForm(QWidget): def __init__(self,parent=None): super(MyForm,self).__init__(parent) def paintEvent(self,event): painter = QPainter(self) painter.drawPixmap(0,0,280,390,QPixmap("1.png")) painter.drawPixmap(300,0,280,390,QBitmap("1.png")) app = QApplication([]) form = MyForm() form.show() app.exec_()
from PyQt4.QtGui import * from PyQt4.QtCore import * class MyForm(QWidget): def __init__(self,parent=None): super(MyForm,self).__init__(parent) self.pix = QPixmap("1.png") self.resize(self.pix.size()) self.setMask(self.pix.mask()) def paintEvent(self,event): painter = QPainter(self) painter.drawPixmap(0,0,self.pix.width(),self.pix.height(),self.pix) app = QApplication([]) form = MyForm() form.show() app.exec_()
上述只是实现不规则窗体的最简单的方式,素材即当遮罩层又当背景图,更灵活的方法是使用一张遮罩层图片,来控制窗体的大小,然后在利用paintEvent方法中重绘其背景图等。
from PyQt4.QtGui import * from PyQt4.QtCore import * class MyForm(QWidget): def __init__(self,parent=None): super(MyForm,self).__init__(parent) self.pix = QBitmap("2.png") self.resize(self.pix.size()) self.setMask(self.pix) def paintEvent(self,event): painter = QPainter(self) painter.drawPixmap(0,0,self.pix.width(),self.pix.height(),QPixmap("3.jpg")) app = QApplication([]) form = MyForm() form.show() app.exec_()
上述采用图片遮罩层的方式,其实还是不灵活,当窗体发生变化的时候,这种方式显示得很不灵活。可以采用QPainter类的绘图方法来动态生成一个遮罩层QPixmap或QBitmap对象,既一张黑白图片,处理一下相应的圆角角度即可。
from PyQt4.QtGui import * from PyQt4.QtCore import * class MyForm(QWidget): def __init__(self,parent=None): super(MyForm,self).__init__(parent) self.mask = QBitmap(400,300) self.mask.fill(Qt.white) painter=QPainter(self.mask) painter.setBrush(QColor(0x000000)) painter.drawRoundRect(0,0,400,300,3,3) self.setMask(self.mask) def paintEvent(self,event): painter = QPainter(self) painter.drawPixmap(0,0,self.width(),self.height(),QPixmap("3.jpg")) app = QApplication([]) form = MyForm() form.show() form.move(400,200) app.exec_()
本篇简单呈现了不规则窗体的几个小应用,浅显易懂,后续章节需要考虑的问题:
- 因重绘窗体后,窗体因隐藏了边框、标题栏,导致窗体不能移动、放大、缩小、拖拽
- 圆角问题,利用drawRoundRect绘制的圆角相比直接用遮罩层的圆角,不够圆滑,即使设置相关抗锯齿参数,也不够理想,我分析了下360、QQ、迅雷的圆角,有一点心得
- 窗体拖拽时,窗体瞬移问题,可以观察一下QVOD软件的拖拽问题
以上几点将在后续章节阐述分析,如果我的blog有什么技术错误,请及时反馈给我。这些学习笔记,希望能给爱好者和新人们一些帮助,晚安!