PyobjC : NSPopover中的NSTextField

0 投票
1 回答
542 浏览
提问于 2025-04-18 15:10

我遇到了和这里提到的同样的问题:在NSPopover中无法编辑NSTextField,尽管设置了可编辑的行为。解决办法似乎是重写NSWindow的canBecomeKeyWindow方法。我想在PyObjC中做同样的事情,但我遇到了一个错误,提示Python签名与隐含的Objective-C签名不匹配

在下面的代码中,如果我把canBecomeKeyWindow_()这一行注释掉,应用程序就能正常运行,但我就无法点击和编辑文本框了。

# from Cocoa import *
from AppKit import NSWindowController, NSApplication, NSApp, NSMaxYEdge, NSImage, NSStatusBar, NSMenu, NSMenuItem, NSVariableStatusItemLength, NSRect
from Cocoa import objc

from Foundation import NSUserNotification, NSUserNotificationCenter, NSObject
from PyObjCTools import AppHelper
import webbrowser
import subprocess
import os
global popover


class TestApp(NSApplication):

    def finishLaunching(self):
        # Make statusbar item
        statusbar = NSStatusBar.systemStatusBar()
        self.statusitem = statusbar.statusItemWithLength_(NSVariableStatusItemLength)
        self.icon = NSImage.alloc().initByReferencingFile_('app-icon.png')
        self.icon.setScalesWhenResized_(True)
        self.icon.setSize_((20, 20))
        self.statusitem.setImage_(self.icon)
        self.statusitem.setHighlightMode_(1)
                # make the menu
        self.menubarMenu = NSMenu.alloc().init()
        self.menuItem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Login', 'loginCallback:', '')
        self.menubarMenu.addItem_(self.menuItem)

        self.quit = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Quit', 'terminate:', '')
        self.menubarMenu.addItem_(self.quit)

        # add menu to statusitem
        self.statusitem.setMenu_(self.menubarMenu)

    def loginCallback_(self, notification):
        # Initiate the contrller with a XIB
        viewController = SimpleXibDemoController.alloc().initWithWindowNibName_("Login")

        # Show the window
        viewController.showWindow_(viewController)
        rect = self.statusitem.valueForKey_('button').frame()
        viewController.popover.showRelativeToRect_ofView_preferredEdge_(rect, self.statusitem.valueForKey_('button'), NSMaxYEdge)


class SimpleXibDemoController(NSWindowController):
    popover = objc.IBOutlet()
    counterTextField = objc.IBOutlet()
    username_field = objc.IBOutlet()
    password_field = objc.IBOutlet()
    submit_button = objc.IBOutlet()

    def canBecomeKeyWindow_(self):
        return 1

    def windowDidLoad(self):
        NSWindowController.windowDidLoad(self)

    @objc.IBAction
    def submit_(self, sender):
        username = self.username_field.stringValue()
        password = self.password_field.stringValue()
        self.updateDisplay(username + ' ' + password)

    def updateDisplay(self, value):
        self.counterTextField.setStringValue_(value)

if __name__ == "__main__":
    app = TestApp.sharedApplication()
    icon = NSImage.alloc().initByReferencingFile_('app-icon.png')
    app.setApplicationIconImage_(icon)
    AppHelper.runEventLoop()

1 个回答

1

看起来你在不该加下划线的地方加了下划线。PyObjC 桥接会把它转换成冒号。此外,Python 中对应的布尔值应该是 True。所以,正确的函数应该是这样的:

def canBecomeKeyWindow(self):
    return True

撰写回答