创建一个子类,其超类只有在被创建时才是已知的

2024-05-28 20:39:22 发布

您现在位置:Python中文网/ 问答频道 /正文

问题

我想要一个方便的方法来创建一个小部件,它有一个QHBoxLayout或QVBoxLayout作为它的布局。小部件的类型可以是最初未知但在创建时指定的任何容器小部件。你知道吗

用法

作为班级装饰师

我重复了很多类似的代码。例如,在添加项目之前,创建布局并将其设置为父窗口小部件的布局。你知道吗

# Insted of this
class JukeBox(QDialog):
    PLAYING, STOPPED, PAUSED = range(3)
    def __init__(self, *args, **kwargs):
        super(JukeBox, self).__init__(self, *args, **kwargs)
        self.state = STOPPED
        self.mainLayout = QVBoxLayout()
        self.playBtn = QPushbutton("Play")
        self.mainLayout.addWidget(self.playBtn)
        self.setLayout(self.mainLayout)

# I want to write this
@BoxWidget(QDialog, Qt.Vertical)
class JukeBox:
    PLAYING, STOPPED, PAUSED = range(3)
    def __init__(self, *args, **kwargs):
        self.state = JukeBox.STOPPED
        self.playBtn = QButton("Play")
        self.layout().addWidget(self.playBtn)

作为可调用

如果我可以使用它作为一个callable,它返回一个特定小部件的实例,这将是一个加号。然后,每次我希望使用一个方便的容器小部件时,我就不一定需要创建一个子类。你知道吗

# Conveniently create a button box
# without having to write a subclass
btnBox = BoxedWidget(QFrame, Qt.Horizontal)
btnBox.addtoLayout(QPushbutton("OK"))
btnBox.addtoLayout(QPushbutton("Cancel")

可能的解决方案

从我所做的研究来看,下面的解决方案似乎可以解决这个问题。你知道吗

重写新方法:尽管我读了很多博客文章,但我真的不了解__new__方法的机制和幕后工作。我的意思是我连正确的问题都不懂。你知道吗

使用元类:我不确定这个解决方案是否可行,但像__new__一样,我不太了解其机制

创建工厂函数:创建BoxedWidget的BoxedMainWindowBoxedDialogBoxedFrame子类。然后,factory函数根据参数决定在创建实例时使用哪种类型。我可能不得不重写不同子类中的某些部分,而其他解决方案可以消除这种需要

创建一个decorator类/函数:我对decorator有点了解。这是我拼凑起来的,不用说它失败了。你知道吗

def boxedWidget(Cls, orient=Qt.Horizontal):

    @functools.wraps
    class BoxedWidget:
        def __init__(self, *args, **kwargs):
            self.widgetInstance = Cls(*args, **kwargs)
            layout = QHBoxLayout()
            if orient == Qt.Vertical:
                layout = QVBoxLayout()
            self.widgetInstance.setLayout(layout)

        def addtoLayout(self, widget, *args, **kwargs):
            layout = self.widgetInstance.layout()
            layout.addWidget(widget, *args, **kwargs)

    return BoxedWidget

错误消息:AttributeError: 'functools.partial' object has no attribute 'layoutWidget'

我对所有的解决方案都持开放态度,尽管我更喜欢第四种。感谢您的帮助。你知道吗


Tags: 方法selfinit部件defargs解决方案qt

热门问题