【问题标题】:Python: Change class type with decorator and keep it's methodsPython:使用装饰器更改类类型并保留其方法
【发布时间】:2015-06-04 18:38:25
【问题描述】:

我想创建一个类,它可以在不同的应用程序及其 API 中使用来创建 UI。为此,我创建了一个名为 ui.py 的模块。该模块内部如下:

from PyQt4 import QtGui


def CreateGui(uiFile, parent=None):
    print "Ui build.."

def GetUiObject(uiClass):
    pUI = uiClass.PARENT
    class ParentUI(pUI):
        def __init__(self, uiFile):
            CreateGui(uiFile, self)
        def __call__(self, cls):
            for func in uiClass.__dict__:
                setattr(cls, func, uiClass.__dict__[func])
    return ParentUI

@GetUiObject
class UI(object):
    PARENT = QtGui.QMainWindow

    def __init__(self, uiFile):
        CreateGui(uiFile)

在应用程序使用的管道模块模块中:

from ui import UI

UI.PARENT = QtGui.QWidget

class Tool_UI(UI):
    def __init__(self, uiFile):
        super(Tool_UI, self).__init__(uiFile)
        print "In Application"


app = QtGui.QApplication(sys.argv)
A = Tool_UI("C:/test/testUi.ui")
A.CreateGui()

但我收到以下错误:

Ui build..
In Application
Traceback (most recent call last):
  File "C:/test/maxUi.py", line 13, in <module>
    A.CreateGui()
RuntimeError: super-class __init__() of type Tool_UI was never called

我做错了什么?

编辑:

cpburnz 回答了代码出错的原因,但它仍然无法正常工作。 我想用另一个具有不同基础的类替换该类。我打开了一个新问题,更好地描述了我的问题以及我尝试过的不同解决方案 (How to rebase or dynamically replace a class with a different base class)。

【问题讨论】:

  • 该代码到底应该做什么?它打算解决什么问题?
  • @ekhumoro:请看我的编辑。

标签: python class inheritance pyqt decorator


【解决方案1】:

这看起来与Python: RuntimeError: super-class __init__() of %S was never called 相关,但您的设置有点不同,所以我会推断以使其更清楚。

Traceback (most recent call last):
  File "C:/test/maxUi.py", line 13, in <module>
    A.CreateGui()
RuntimeError: super-class __init__() of type Tool_UI was never called

这意味着在Tool_UI 的类层次结构中的某个地方super(...).__init__(...) 没有被调用。这似乎是由QObjectQWidget 提出的。 查看GetUiObject()中定义的类,并没有调用super的init 即使父类pUIQWidget。您很可能需要添加 调用那里的超级初始化:

def GetUiObject(uiClass):
    pUI = uiClass.PARENT

    class ParentUI(pUI):

        def __init__(self, uiFile):
            super(ParentUI, self).__init__() # <-- Missing.
            CreateGui(uiFile, self)

        def __call__(self, cls):
            for func in uiClass.__dict__:
                setattr(cls, func, uiClass.__dict__[func])

    return ParentUI

【讨论】:

  • 非常感谢。我想在尝试解决这个问题数小时后,我的代码变得盲目了。
  • 错误消失了,但问题没有解决。请看我的编辑。您对我的问题有什么解决方案吗?
  • @MagSec 我不知道这是否会有所帮助,但在您的后续问题中尝试覆盖 __class__ 看起来与 Unable to change __class__ of PySide.QtGui objects 大致相关。
  • 我认为这不起作用,因为 PySide 使用的是 Shiboken 而 PyQt 不是。所以它们仍然是不兼容的。要做一个猴子补丁,我需要将每个基础预定义为一个类,这不是我想要在这个模块中做的事情
猜你喜欢
  • 2020-02-29
  • 2014-01-14
  • 2014-10-08
  • 1970-01-01
  • 2022-08-15
  • 1970-01-01
  • 2020-01-11
  • 2018-07-14
  • 2014-03-18
相关资源
最近更新 更多