在Python/PyObjC中如何继承NSPanel?

2024-09-30 08:29:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在将Objective-C/Cocoa的一个小库移植到Python/PyObjC中。 我对实施的方式感到困惑。在

原始代码如下所示:

@implementation HUDWindow
- (id)initWithContentRect:(NSRect)contentRect 
                styleMask:(unsigned int)styleMask 
                  backing:(NSBackingStoreType)bufferingType 
                    defer:(BOOL)flag 
{
    if (self = [super initWithContentRect:contentRect 
                                styleMask:NSBorderlessWindowMask 
                                  backing:bufferingType 
                                    defer:flag]) {
        // initialize code here
             :
             :
             :
             :
             :
             :
        return self;
    }
}

在头文件中,HUDWindow类继承NSPanel。 就我读到的代码而言,初始化是这样进行的:

  1. HUDWindow的initContentRect重写了NSPanel的initContentRect。在
  2. 在HUDWindow的initContentRect内部,NSPanel的initContentRect被调用并得到“self”的结果。在

首先,我像这样编写python代码。这是逐字翻译:

^{pr2}$

它没有工作,因为self只是NSPanel的一个实例。我不能调用我从原始obj-c代码移植的任何令人上瘾的函数。在

所以我把代码改成这样:

^{3}$

效果好一点。至少,我可以在这个初始化函数中调用其他函数。 但在initialize函数之外,我不能调用从原始代码移植的其他函数。在

所以我试着这样做:

class HUDWindow(NSPanel):
    def initWithContentRect_styleMask_backing_defer_(self, rect, style, buf, flag):
        self.window = NSPanel.initWithContentRect_styleMask_backing_defer_(
            rect, NSBorderlessWindowMask, buf, flag)
        # initialize code here
             :
             :
             :
             :
             :
             :
         self.window.setTitle_ = self.setTitle_
         return self.window

没用。我不能在创建实例后重写或添加函数。在

现在我觉得我做错了。有没有通用的方法来继承像NSPanel或NPWindow这样的类?在


Tags: 函数代码selfwindowdeferflaginitializebacking
1条回答
网友
1楼 · 发布于 2024-09-30 08:29:15

你的第一个解决方案是正确的。第二种方式是你不需要写的。在

然而,也存在一些问题。在

首先,这个代码:

self = NSPanel.initWithContentRect_styleMask_backing_defer_(rect, NSBorderlessWindowMask, buf, flag)

…相当于此ObjC代码:

^{pr2}$

…当你想要的是:

self = [super initWithContentRect:rect 
                        styleMask:NSBorderlessWindowMask
                          backing:buf
                            defer:flag]

后者的PyObjC相当于:

self = super().initWithContentRect_styleMask_backing_defer_(rect, NSBorderlessWindowMask, buf, flag)

或者,在2.x中:

self = super(HUDWindow, self).initWithContentRect_styleMask_backing_defer_(rect, NSBorderlessWindowMask, buf, flag)

在ObjC中,super不是超类,而是一个特殊的魔法对象,它实际上是“作为超类实例的自我”。它几乎与python3的super(),或者不那么神奇的python2super,PyObjC做了额外的工作,意味着您可以忽略“几乎”。在

您所做的是(尝试)初始化NSPanel类对象(或者可能将PyObjC桥的类对象初始化为NSPanel,我不确定是哪个),或者甚至可能尝试将rect初始化为NSPanel。无论您在做什么,它都不可能初始化您的self实例。(并且将结果赋给self与在ObjC中做的事情不同。在PyObjC中,它通常仍然是惯用的风格,但是不要被它误导;它的唯一效果是如果在初始值设定项方法中再次使用self。无论如何,这最多可以掩盖ObjC中的问题,而不是修复它……)因此,从这个方法返回后,self仍然是在调用任何东西之前分配但未初始化的{}实例。在

这一点在本教程的早期部分,即Two Phase Instantiation中进行了解释。在

相关问题 更多 >

    热门问题