Failed to modify __class__ of PySide.QtGui objects

I used PyQt4 quite a lot - sometimes I like to overload some objects so that I can add some functions. This works fine in PyQt4, for example:

from PyQt4 import QtGui
button = QtGui.QPushButton()
class MyPushButton(QtGui.QPushButton): pass
button.__class__ = MyPushButton

However, I am trying to adapt some code so that it uses PySide instead of PyQt4. I understand that they must have the same functionality. PySide will not let me do the same.

from PySide import QtGui
button = QtGui.QPushButton()
class MyPushButton(QtGui.QPushButton): pass
button.__class__ = MyPushButton

These errors are:

TypeError: __class__ assignment: only for heap types

Is there any other way to change the class of my object to avoid this error? I'm not quite sure what this causes.

NOTE. I need to change the class of an object after it is created as the object is created in the library that pyuic compiled. Also, my PySide installation does not have a uic module.

+3
source share
2

PySide Shiboken CPython Qt ++. Qt python, QPushButton, ++, __class__.

>>> button = QPushButton()
>>> button.__class__ = MyButton
TypeError: __class__ assignment: only for heap types

Shiboken, ( ) , ():

import types

def override_text(self):
    return 'overridden'

# Bind override_text() to button.
button.text = types.MethodType(override_text, button, QPushButton)

, QPushButton MyButton, MyButton QPushButton . MyButton QPushButton , MyButton QPushButton.

MyButton QPushButton.

class MyButton(QPushButton):

    def text(self):
        # This will override QPushButton text() method.
        print("inside MyButton.text()")
        return QPushButton.text(self)
  • . . super() TypeError, self QPushButton MyButton .

, mixin, MyButtonOverrides:

class MyButtonOverrides(object):

    def text(self):
        # This will override QPushButton text() method.
        print("inside MyButtonOverrides.text()")
        return self.__class__.text(self)
  • . QPushButton.text() self.__class__ MyButtonOverrides .

extend_instance(), MyButton ( 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''
+3

__class__ . Qt Designer, .

Qt Designer "...". " " (, "MyPushButton" ) " " python , (, "myapp" "myapp.gui", - ).

"", "", "QPushButton" "MyPushButton" " ".

ui- pyuic pyside-uic, :

class Ui_Window(object):
    def setupUi(self, Window):
        ...
        self.button = MyPushButton(Window)
        self.button.setObjectName("button")
        ...

from myapp import MyPushButton

, MyPushButton, __class__.

PyQt, PySide.

+1

All Articles