实战PyQt5: 108-创建不规则窗口
文章插图
如何创建不规则窗口在一些应用中 , 使用不规则的窗口会使应用外观显得更有个性 , 更符合应用所要表达的功能特点 , 比如一个炫酷的播放器 , 一个圆形的模拟时钟等 。 在QWidget中提供函数setMask()可以方便地实现不规则窗口的功能 。
setMask()的作用是为调用它的Widget增加一个遮罩 , 在遮罩所选区域之外的部分是透明的 , Widget显示出来的区域就是遮罩所控制的区域 。 setMask()有两种形式:
- setMask(self, rgn: QRegiom), 它使用一个QRegion对象来确定遮罩区域 。
- setMask(self, bmp: QBitmap), 它是一个QBitmap对象 , 其中像素值为0的部分表示是透明的 , 在实际使用中 , 常常使用QPixmap.mask()函数从一个PNG格式的图像中的透明度部分获得遮罩 。
1. 创建一个窗口 , 并将其设置成无边框模式
2. 使用setMask方法设置遮罩
3. 重载其mousePressEvent()和mouseMoveEvent()方法实现对窗口的移动操作
【实战PyQt5: 108-创建不规则窗口】4. 重载paintEvent()方法实现窗口的绘制
测试代码在PyQt样例代码shapedclock.py的基础上 , 实现一个圆形的模拟时钟 , 在时钟绘制上 , 增添了秒针支持 。完整代码如下:
import sysfrom PyQt5.QtCore import Qt, QPoint, QSize, QTime, QTimerfrom PyQt5.QtGui import QColor, QPainter, QPolygon, QRegion, QPainterPathfrom PyQt5.QtWidgets import QAction, QApplication, QWidget class MyShapedClock(QWidget):#时针形状hourHand = QPolygon([QPoint(7, 8),QPoint(-7, 8),QPoint(0, -40)])#分针形状minuteHand = QPolygon([QPoint(7, 8),QPoint(-7, 8),QPoint(0, -70)])#时针颜色hourColor = QColor(127, 0, 127)minuteColor = QColor(0, 127, 127, 191)secondColor = QColor(255, 0, 0, 191)def __init__(self, parent=None):#创建一个无边框的窗口super(MyShapedClock, self).__init__(parent, Qt.FramelessWindowHint | Qt.WindowSystemMenuHint)# 设置窗口标题self.setWindowTitle('实战PyQt5: 圆形模拟时针')#定时器,每秒刷新timer = QTimer(self)timer.timeout.connect(self.update)timer.start(1000)#右键退出菜单aQuit = QAction('退出(&X)', self, shortcut='Ctrl+Q',triggered=QApplication.instance().quit)self.addAction(aQuit)self.setContextMenuPolicy(Qt.ActionsContextMenu)self.setToolTip('使用鼠标左键拖动时钟 。 \n''使用鼠标右键打开上下文菜单 。 ')def mousePressEvent(self, event):if event.button() == Qt.LeftButton:#计算拖动位置self.dragPosition = event.globalPos() - self.frameGeometry().topLeft()event.accept()def mouseMoveEvent(self, event):if event.buttons() == Qt.LeftButton:#移动时钟self.move(event.globalPos() - self.dragPosition)event.accept()def paintEvent(self, event):side = min(self.width(), self.height())time = QTime.currentTime()painter = QPainter(self)#启动抗锯齿操作painter.setRenderHint(QPainter.Antialiasing)#平移到窗口中心点painter.translate(self.width()/2, self.height()/2)#缩放比例painter.scale(side / 200.0, side / 200.0)#==== 绘制时针 ====#painter.setPen(Qt.NoPen)painter.setBrush(MyShapedClock.hourColor)painter.save()#旋转时针到正确位置painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)))painter.drawConvexPolygon(MyShapedClock.hourHand)painter.restore()#==== 绘制小时刻度 ====#painter.setPen(MyShapedClock.hourColor)for i in range(12):painter.drawLine(88, 0, 96, 0)painter.rotate(30.0)#==== 绘制分针 ====#painter.setPen(Qt.NoPen)painter.setBrush(MyShapedClock.minuteColor)painter.save()painter.rotate(6.0 * (time.minute() + time.second() / 60.0))painter.drawConvexPolygon(MyShapedClock.minuteHand)painter.restore()#==== 绘制分针刻度 ====#painter.setPen(MyShapedClock.minuteColor)for j in range(60):if(j % 5) != 0:painter.drawLine(94, 0, 96, 0)painter.rotate(6.0)#==== 绘制秒针 ====#painter.setPen(Qt.NoPen)painter.setBrush(MyShapedClock.secondColor)painter.drawEllipse(-4, -4, 8, 8)path = QPainterPath()path.addRoundedRect(-1, -1, 80, 2, 1, 1)painter.save()painter.rotate(6.0 * time.second())painter.fillPath(path, MyShapedClock.secondColor)painter.restore()def resizeEvent(self, event):w = self.width()h = self.height()side = min(w, h)#为窗口设置一个圆形遮罩maskedRegion = QRegion(w/2 - side/2, h/2 - side/2, side, side, QRegion.Ellipse)#关键函数!!!!!!self.setMask(maskedRegion)def sizeHint(self):return QSize(320, 320)if __name__ == '__main__':app = QApplication(sys.argv)windows = MyShapedClock()windows.show()sys.exit(app.exec())
运行结果如下图:文章插图
不规则窗口:圆盘时钟
本文知识点
- setMask()两种方式实现不规则窗口的绘制;
- QPainter的空间变换函数translate, scale, rotate的使用方法;
- 无边框窗口移动功能的实现;
- Wireshark数据包分析实战:TCP报文段重组
- Python爬虫采集网易云音乐热评实战
- Django实战016:django中使用redis详解
- HTTP实战之Wireshark抓包分析
- Wireshark数据包分析实战:网卡卸载
- Python数据分析:数据可视化实战教程
- 实战经验:电商平台遭遇CC攻击,我们是如何应对的?
- Tencent IN对话 | 八位互联网实战家,实战智慧营销商学院
- HLS实战之Wireshark抓包分析
- Vue实战091:Vue项目部署到nginx服务器