qt 设置窗口位置_实战PyQt5: 108-创建不规则窗口

91ff871763503f38cab89111933d3dc1.png

如何创建不规则窗口

在一些应用中,使用不规则的窗口会使应用外观显得更有个性,更符合应用所要表达的功能特点,比如一个炫酷的播放器,一个圆形的模拟时钟等。在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()方法实现对窗口的移动操作

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('使用鼠标左键拖动时钟。'                        '使用鼠标右键打开上下文菜单。')            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())

运行结果如下图:

9a7e9c40094cc72f7ceeed9edf20caa1.gif

不规则窗口:圆盘时钟

本文知识点

  • setMask()两种方式实现不规则窗口的绘制;
  • QPainter的空间变换函数translate, scale, rotate的使用方法;
  • 无边框窗口移动功能的实现;
  • 使用QPainterPath绘制填充的圆角矩形。

喜欢本文内容就多多关注,评论,收藏,点赞,和转发。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值