[PyQt]不规则窗体的实现之一

[PyQt]不规则窗体的实现之一

知识点

  PyQt一般实现的窗体就是当前操作系统原生窗体的样式,ubuntu下的窗体还不错,window下的就难看了,虽然平时应用程序关心的往往是业务和功能,但是偶尔我们也需要制作一些个性的窗体样式,如QQ、360、千千静听等,这种漂亮个性的窗体,很能吸引大众的眼球。

  实现不规则窗体,我采用继承QWidget这个部件基类并重绘之,有几个知识点:

    - 重写paintEvent事件,可以绘制窗体的背景图片

    - 调用setMask方法设置窗体的遮罩层,可以个性化窗体,掩码图片黑色部分即是要显示的,白色即是要隐藏的

    - 要理解QPixmap和QBitmap的区别,QBitmap是QPixmap的子类别,提供单色图像

区别QPixmap和QBitmap的小实例
- 素材图片:1.png

[PyQt]不规则窗体的实现之一_第1张图片

- 实例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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_()
- 运行效果

[PyQt]不规则窗体的实现之一_第2张图片

不规则窗体的小实例
- 实例代码:继续使用1.png
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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_()
- 运行结果

[PyQt]不规则窗体的实现之一_第3张图片

不是小结

  上述只是实现不规则窗体的最简单的方式,素材即当遮罩层又当背景图,更灵活的方法是使用一张遮罩层图片,来控制窗体的大小,然后在利用paintEvent方法中重绘其背景图等。

不规则窗体的小实例
- 素材图片:2.png、3.jpg

[PyQt]不规则窗体的实现之一_第4张图片

[PyQt]不规则窗体的实现之一_第5张图片

- 测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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_()
- 运行结果

[PyQt]不规则窗体的实现之一_第6张图片

不是小结

  上述采用图片遮罩层的方式,其实还是不灵活,当窗体发生变化的时候,这种方式显示得很不灵活。可以采用QPainter类的绘图方法来动态生成一个遮罩层QPixmap或QBitmap对象,既一张黑白图片,处理一下相应的圆角角度即可。

不规则窗体的小实例
- 实例代码:继续使用3.jpg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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_()
- 运行结果

[PyQt]不规则窗体的实现之一_第7张图片

小结

  本篇简单呈现了不规则窗体的几个小应用,浅显易懂,后续章节需要考虑的问题:

    - 因重绘窗体后,窗体因隐藏了边框、标题栏,导致窗体不能移动、放大、缩小、拖拽

    - 圆角问题,利用drawRoundRect绘制的圆角相比直接用遮罩层的圆角,不够圆滑,即使设置相关抗锯齿参数,也不够理想,我分析了下360、QQ、迅雷的圆角,有一点心得

    - 窗体拖拽时,窗体瞬移问题,可以观察一下QVOD软件的拖拽问题

  以上几点将在后续章节阐述分析,如果我的blog有什么技术错误,请及时反馈给我。这些学习笔记,希望能给爱好者和新人们一些帮助,晚安!

你可能感兴趣的:([PyQt]不规则窗体的实现之一)