我经常使用PyQt4—有时我喜欢重载一些对象,以便添加一些功能。这在PyQt4中运行良好,例如:
from PyQt4 import QtGui
button = QtGui.QPushButton()
class MyPushButton(QtGui.QPushButton): pass
button.__class__ = MyPushButton
不过,我正在尝试修改我的一些代码,以便它使用PySide而不是PyQt4。我的理解是它们应该具有相同的功能。PySide不允许我做同样的事情。在
^{pr2}$此错误包含:
TypeError: __class__ assignment: only for heap types
有没有其他方法可以更改对象的类以避免此错误?我不太确定是什么原因造成的。在
注意:由于对象是在pyuic编译的库中创建的,所以我需要在创建后更改对象的类。另外,我的PySide安装没有uic模块。
猴子修补
__class__
完全没有必要。相反,您应该promoteQt Designer中的相关小部件,以便它们自动使用您的子类。在为此,在QtDesigner中,右键单击小部件并选择“升级到…”。在对话框中,将“Promoted class name”设置为子类(例如“MyPushButton”),并将“Header file”设置为包含子类的模块的python导入路径(例如“myapp”,或myapp.gui“,或者别的什么)。在
现在单击“Add”,然后单击“Promote”,您将在objectinspector窗格中看到类从“QPushButton”更改为“mybutton”。在
当您使用
pyuic
或pyside-uic
重新生成ui模块时,它将包含如下代码:因此,升级的按钮将被创建为
MyPushButton
的实例,不再需要对__class__
进行黑客攻击。在这种提升小部件的技术对PyQt和PySide都有效。在
PySide使用Shiboken为Qt生成CPython绑定 它的C++类。所有Qt python类,如
QPushButton
都是 在C++中实现,这就是为什么你不能覆盖^ {< CD2> }。在根据Shiboken的文档,您可以monkey patch (or duck punch) 已经实例化的对象上的方法,只要这些方法 虚拟(可重写):
^{pr2}$更进一步,您可以将
QPushButton
子类为MyButton
,并且 将来自MyButton
的方法动态注入QPushButton
实例。使MyButton
成为QPushButton
的子类是纯粹的 可选,但允许您创建自己的MyButton
实例 除了修改后的QPushButton
实例。在让我们将
MyButton
定义为QPushButton
的子类。在super()
以TypeError
失败,因为self实际上是QPushButton
当注射该方法时,不是MyButton
。在或者,如果您想采用更多的mixin方法,让我们定义
MyButtonOverrides
:self.__class__
直接调用QPushButton.text()
因为您不会直接使用MyButtonOverrides
。在现在让我们定义}
实例:
extend_instance()
,它将注入您的覆盖 方法从MyButton
(或MyButtonOverrides
)到{如果您希望您的类方法保持绑定到它们的原始类 (例如,
MyButton
)然后使用以下方法:通过我的测试,这在Python2.7和3.3中可以工作,但是应该 在2.6+和3+上工作。在
最后要修改按钮,请使用
extend_instance()
。在相关问题 更多 >
编程相关推荐