我想要一种方便的方法来创建具有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)
如果我可以将其用作可回调函数,则返回一个特定小部件的实例,该实例将为加号。这样,每次使用方便的容器小部件时,就不必创建子类。
# 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'
尽管我喜欢第四个解决方案,但我对所有解决方案都持开放态度。任何帮助表示赞赏。