当前位置:首页>python>乱写CATOptTK过程中的笔记 - Python/PySide6属性

乱写CATOptTK过程中的笔记 - Python/PySide6属性

  • 2026-08-27 13:39:25
乱写CATOptTK过程中的笔记 - Python/PySide6属性
概述
仅用于总结写CAT优化工具包过程中的一些知识点。本次记录的内容是Python提供的property方法和PySide6中QtCore提供的Property类。

Python中的property方法

property是Python提供的一种装饰器(装饰器的简单介绍可以参考乱写CATOptTK过程中的笔记 - 装饰器),是用来修饰方法的,被修饰的方法可以像访问属性一样被访问。它的主要作用是防止用户直接修改属性。假如说我们有一个Data类,其中有一个方法是获取Data的数据:
class Data():    data = 100    def data_value(self):        return self.dataif __name__=="__main__":    d = Data()    print(d.data) # 100    d.data = 10    print(d.data) # 10
可以发现用户是可以修改Data的,如果仅仅将用户获取的数据变为“只读”(之所以只读加引号,是因为通过实现getter、setter、deleter方法是可以实现将方法变成完全和属性一样的,但此处不做介绍),则可以使用property装饰器。
class Data():    data = 100    @property    def data_value(self):        return self.dataif __name__=="__main__":    d = Data()    print(d.data_value) # 100    d.data_value = 10    print(d.data) # AttributeError: property 'data_value' of 'Data' object has no setter
可以发现,如果不实现setter、getter、deleter方法,property所装饰的函数对用户来说就完全变成了一个只读属性。

PySide6.QtCore.Property

PySide6中的Property是Qt属性系统的一部分,用于声明Qt属性。因此与Python提供的property方法相比,Property还支持属性变化信号、属性动画、样式表支持等Qt所特有的功能。在使用上,QtCore.Property需要额外输入一个类型参数。
pp = QtCore.Property(int, readPP, setPP)    # PySide versionpp = property(readPP, setPP)                # Python version
Qt for Python帮助文档提供的案例如下:
 from PySide6.QtCore import QObject, Property class MyObject(QObject):     def __init__(self, startval=42):         QObject.__init__(self)         self.ppval = startval     def readPP(self):         return self.ppval     def setPP(self, val):         self.ppval = val     pp = Property(int, readPP, setPP) obj = MyObject() obj.pp = 47 print(obj.pp)

实例

在实现一个通用卡片时,将卡片的圆角尺寸Property化。
from PySide6.QtWidgets import QFramefrom PySide6.QtCore import Signal, Property, Qtfrom PySide6.QtGui import QColor, QPainter, QPainterPathfrom ...common.style_sheet import isDarkThemefrom ...common.animation import BackgroundAnimationWidgetclass CardWidget(BackgroundAnimationWidget, QFrame):    ''' card widget '''    # 创建一个点击信号    clicked = Signal()    def __init__(self, parent=None):        super().__init__(parent=parent)        self._isClickEnabled = False        self._borderRadius = 5    ...    def getBorderRadius(self):        return self._borderRadius    def setBorderRadius(self, radius: int):        self._borderRadius = radius        self.update()    def paintEvent(self, e):        painter = QPainter(self)        painter.setRenderHint(QPainter.Antialiasing)        w, h = self.width(), self.height()        r = self.borderRadius        d = 2*r        isDark = isDarkTheme()        # draw top border        path = QPainterPath()        path.arcMoveTo(1, h-d-1, d, d, 240)        path.arcTo(1, h - d - 1, d, d, 225, -60)        path.lineTo(1, r)        path.arcTo(1, 1, d, d, -180, -90)        path.lineTo(w - r, 1)        path.arcTo(w - d - 1, 1, d, d, 90, -90)        path.lineTo(w - 1, h - r)        path.arcTo(w - d - 1, h - d - 1, d, d, 0, -60)        topBorderColor = QColor(0, 0, 0, 20)        if isDark:            if self.isPressed:                topBorderColor = QColor(255, 255, 255, 18)            elif self.isHover:                topBorderColor = QColor(255, 255, 255, 13)        else:            topBorderColor = QColor(0, 0, 0, 15)        painter.strokePath(path, topBorderColor)        # draw bottom border        path = QPainterPath()        path.arcMoveTo(1, h - d - 1, d, d, 240)        path.arcTo(1, h - d - 1, d, d, 240, 30)        path.lineTo(w - r - 1, h - 1)        path.arcTo(w - d - 1, h - d - 1, d, d, 270, 30)        bottomBorderColor = topBorderColor        if not isDark and self.isHover and not self.isPressed:            bottomBorderColor = QColor(0, 0, 0, 27)        painter.strokePath(path, bottomBorderColor)        # draw background        painter.setPen(Qt.NoPen)        rect = self.rect().adjusted(1, 1, -1, -1)        painter.setBrush(self.backgroundColor)        painter.drawRoundedRect(rect, r, r)    borderRadius = Property(int, getBorderRadius, setBorderRadius)
欢迎点赞、分享、喜欢

最新文章

随机文章