pyqt 开源项目源码阅读

简介:

项目地址:

zhiyiYo/PyQt-Frameless-Window: A cross-platform frameless window based on pyqt5, support Win32, Linux and macOS. (github.com)

自定义组件button:

 

button继承结构:

自定义button 继承 QAbstractButton 继承 QWidget:

QWidget 简介:

打开qt设计师

 qwidget:大概有的功能:

0:设置对象id

1:设置可用

2: 设置 当前的xy位置 与宽高

3:设置字体

4:设置移动的光标形状

5:设置提示信息

6:设置qss样式

QAbstractButton简介:

 1: 设置文本

2: 设置图标

3: 设置图标大小

自定义基类组件TitleBarButton:

需求:光标移动到组件, 离开组件,和按下组件的时候改变颜色。

设计思路:

定义3个状态的枚举类型, 定义进入,离开,按下三类事件,控制button状态。 通过_getColors方法获取当前状态下的颜色, 由子类完成动画绘制。

class TitleBarButtonState(Enum):
    """ Title bar button state """
    NORMAL = 0
    HOVER = 1
    PRESSED = 2

定义状态背景颜色:

        self._normalBgColor = QColor(0, 0, 0, 0)
        self._hoverBgColor = QColor(0, 0, 0, 26)
        self._pressedBgColor = QColor(0, 0, 0, 51)

更新状态:

self.update() 是基类 Qwidget的方法,作用是调用 绘制事件 paintEvent

    def setState(self, state):
        """ set the state of button

        Parameters
        ----------
        state: TitleBarButtonState
            the state of button
        """
        self._state = state
        self.update()

定义进入 离开 按下 事件:

    def enterEvent(self, e):
        self.setState(TitleBarButtonState.HOVER)
        super().enterEvent(e)

    def leaveEvent(self, e):
        self.setState(TitleBarButtonState.NORMAL)
        super().leaveEvent(e)

    def mousePressEvent(self, e):
        if e.button() != Qt.LeftButton:
            return

        self.setState(TitleBarButtonState.PRESSED)
        super().mousePressEvent(e)

获取状态的颜色:

    def _getColors(self):
        """ get the icon color and background color """
        if self._state == TitleBarButtonState.NORMAL:
            return self._normalColor, self._normalBgColor
        elif self._state == TitleBarButtonState.HOVER:
            return self._hoverColor, self._hoverBgColor

        return self._pressedColor, self._pressedBgColor

自定义组件SvgTitleBarButton:

需求:读取svg图片,作为button的 icon。

设计思路:

读取svg图片。

绘制图片。

    def __init__(self, iconPath, parent=None):
        """
        Parameters
        ----------
        iconPath: str
            the path of icon

        parent: QWidget
            parent widget
        """
        super().__init__(parent)
        self._svgDom = QDomDocument()
        self.setIcon(iconPath)
    def setIcon(self, iconPath):
        """ set the icon of button

        Parameters
        ----------
        iconPath: str
            the path of icon
        """
        f = QFile(iconPath)
        f.open(QFile.ReadOnly)
        self._svgDom.setContent(f.readAll())
        f.close()

QDomDocument: xml文件操作类

QFile: 文件操作类

绘制图片: paintEvent的触发条件是 基类状态改变时调用的update()。

    def paintEvent(self, e):
        painter = QPainter(self)
        painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
        color, bgColor = self._getColors()

        # draw background
        painter.setBrush(bgColor)
        painter.setPen(Qt.NoPen)
        painter.drawRect(self.rect())

        # draw icon
        color = color.name()
        pathNodes = self._svgDom.elementsByTagName('path')
        for i in range(pathNodes.length()):
            element = pathNodes.at(i).toElement()
            element.setAttribute('stroke', color)

        renderer = QSvgRenderer(self._svgDom.toByteArray())
        renderer.render(painter, QRectF(self.rect()))

自定义用户button:

class CloseButton(SvgTitleBarButton):
    """ Close button """

    def __init__(self, parent=None):
        super().__init__(":/qframelesswindow/close.svg", parent)
        self.setHoverColor(Qt.white)
        self.setPressedColor(Qt.white)
        self.setHoverBackgroundColor(QColor(232, 17, 35))
        self.setPressedBackgroundColor(QColor(241, 112, 122))

总结:

基类TitleBarButton,实现了进入,离开,按下, 三个事件。 提供一个方法获取当前事件的颜色,用户配合paintEvent 事件完成动画绘制。

qwidget 事件

def enterEvent(self, e):

def leaveEvent(self, e):

def mousePressEvent(self, e):

def paintEvent(self, e): update()将调用此事件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值