首页 > 解决方案 > 创建一个子类,其超类仅在创建时才知道

问题描述

问题

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

用法

作为班级装饰员

我重复了很多类似的代码。IE。在添加项目之前创建布局并将其设置为父小部件的布局。

# 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)

作为可调用

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

# 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__ :尽管我阅读了所有博客文章,但我真的不了解该方法的机制和幕后工作。我的意思是我的理解还不够,甚至无法提出正确的问题。

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

创建工厂函数:创建BoxedWidget的BoxedMainWindow, BoxedDialog,子类。BoxedFrame然后,工厂函数根据参数决定在创建实例时使用哪种类型。我可能必须覆盖各种子类中的某些部分,而其他解决方案可以消除这种需要

创建一个装饰器类/函数:我有点了解装饰器。这是我一起破解的,不用说它失败了。

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'

我对所有解决方案持开放态度,尽管我更喜欢第四个。任何帮助表示赞赏。

标签: pythondesign-patternspyqtdecoratorfactory

解决方案


推荐阅读