PySide 使用Shiboken http://shiboken.readthedocs.org/en/latest/生成 Qt 的 CPython 绑定
它的 C++ 类。所有 Qt python 类,例如QPushButton
是
用 C++ 实现,这就是为什么你不能覆盖__class__
.
>>> button = QPushButton()
>>> button.__class__ = MyButton
TypeError: __class__ assignment: only for heap types
根据 Shiboken 的文档,您可以猴子补丁(或鸭拳) http://shiboken.readthedocs.org/en/latest/wordsofadvice.html#duck-punching-and-virtual-methods已经实例化的对象上的方法,只要这些方法是
虚拟(可重写):
import types
def override_text(self):
return 'overridden'
# Bind override_text() to button.
button.text = types.MethodType(override_text, button, QPushButton)
更进一步,你可以细分QPushButton
as MyButton
, 和
动态注入方法MyButton
进入QPushButton
实例。制作MyButton
的一个子类QPushButton
纯粹是
可选,但允许您创建自己的实例MyButton
除了修改后的QPushButton
实例。
让我们定义一下MyButton
作为一个子类QPushButton
.
class MyButton(QPushButton):
def text(self):
# This will override QPushButton's text() method.
print("inside MyButton.text()")
return QPushButton.text(self)
- 注意:您必须使用旧式的调用父类方法。
super()
失败了TypeError
因为自我实际上是一个QPushButton
而不是一个MyButton
当方法被注入时。
或者,如果您想采用更多混合方法,让我们定义MyButtonOverrides
:
class MyButtonOverrides(object):
def text(self):
# This will override QPushButton's text() method.
print("inside MyButtonOverrides.text()")
return self.__class__.text(self)
- 注意:您可以致电
QPushButton.text()
直接通过self.__class__
因为你不会使用MyButtonOverrides
直接地。
现在让我们定义extend_instance()
这将注入你的覆盖
方法来自MyButton
(or MyButtonOverrides
) 进入QPushButton
实例:
import inspect
def extend_instance(obj, cls):
for name, attr in vars(cls).items():
if inspect.isroutine(attr):
# Bind instance, class and static methods to *obj*.
setattr(obj, name, attr.__get__(obj, obj.__class__))
如果您希望您的类方法保持与其原始类的绑定
(例如。,MyButton
)然后使用以下内容:
def extend_instance(obj, cls):
for name, attr in vars(cls).items():
if inspect.isroutine(attr):
if isinstance(attr, classmethod):
# Bind class methods to *cls*.
setattr(obj, name, attr.__get__(cls, cls))
else:
# Bind instance and static methods to *obj*.
setattr(obj, name, attr.__get__(obj, obj.__class__))
通过我的测试,这在 Python 2.7 和 3.3 中有效,但应该
适用于 2.6+ 和 3+。
最后修改按钮,使用extend_instance()
.
>>> button = QPushButton()
>>> extend_instance(button, MyButton)
>>> button.text()
inside MyButton.text()
u''