如何使用 Cocoa 和 Python (PyObjC) 创建状态栏项目?

发布于 2024-07-05 21:20:06 字数 563 浏览 6 评论 0原文

我在 XCode 中创建了一个全新的项目,并在我的 AppDelegate.py 文件中包含以下内容:

from Foundation import *
from AppKit import *

class MyApplicationAppDelegate(NSObject):
    def applicationDidFinishLaunching_(self, sender):
        NSLog("Application did finish launching.")

        statusItem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength)
        statusItem.setTitle_(u"12%")
        statusItem.setHighlightMode_(TRUE)
        statusItem.setEnabled_(TRUE)

但是,当我启动应用程序时,没有显示状态栏项目。 main.py 和 main.m 中的所有其他代码都是默认的。

I have created a brand new project in XCode and have the following in my AppDelegate.py file:

from Foundation import *
from AppKit import *

class MyApplicationAppDelegate(NSObject):
    def applicationDidFinishLaunching_(self, sender):
        NSLog("Application did finish launching.")

        statusItem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength)
        statusItem.setTitle_(u"12%")
        statusItem.setHighlightMode_(TRUE)
        statusItem.setEnabled_(TRUE)

However, when I launch the application no status bar item shows up. All the other code in main.py and main.m is default.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

秉烛思 2024-07-12 21:20:06

上面使用 .retain() 是必需的,因为 statusItem 在从 applicationDidFinishLaunching() 方法返回时被销毁。 使用 self.statusItem 将该变量绑定为 MyApplicationAppDelegate 实例中的字段。

这是一个修改后的示例,不需要 .xib / 等...

from Foundation import *
from AppKit import *
from PyObjCTools import AppHelper

start_time = NSDate.date()


class MyApplicationAppDelegate(NSObject):

    state = 'idle'

    def applicationDidFinishLaunching_(self, sender):
        NSLog("Application did finish launching.")

        self.statusItem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength)
        self.statusItem.setTitle_(u"Hello World")
        self.statusItem.setHighlightMode_(TRUE)
        self.statusItem.setEnabled_(TRUE)

        # Get the timer going
        self.timer = NSTimer.alloc().initWithFireDate_interval_target_selector_userInfo_repeats_(start_time, 5.0, self, 'tick:', None, True)
        NSRunLoop.currentRunLoop().addTimer_forMode_(self.timer, NSDefaultRunLoopMode)
        self.timer.fire()

    def sync_(self, notification):
        print "sync"

    def tick_(self, notification):
        print self.state


if __name__ == "__main__":
    app = NSApplication.sharedApplication()
    delegate = MyApplicationAppDelegate.alloc().init()
    app.setDelegate_(delegate)
    AppHelper.runEventLoop()

The above usage of .retain() is required because the statusItem is being destroyed upon return from the applicationDidFinishLaunching() method. Bind that variable as a field in instances of MyApplicationAppDelegate using self.statusItem instead.

Here is a modified example that does not require a .xib / etc...

from Foundation import *
from AppKit import *
from PyObjCTools import AppHelper

start_time = NSDate.date()


class MyApplicationAppDelegate(NSObject):

    state = 'idle'

    def applicationDidFinishLaunching_(self, sender):
        NSLog("Application did finish launching.")

        self.statusItem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength)
        self.statusItem.setTitle_(u"Hello World")
        self.statusItem.setHighlightMode_(TRUE)
        self.statusItem.setEnabled_(TRUE)

        # Get the timer going
        self.timer = NSTimer.alloc().initWithFireDate_interval_target_selector_userInfo_repeats_(start_time, 5.0, self, 'tick:', None, True)
        NSRunLoop.currentRunLoop().addTimer_forMode_(self.timer, NSDefaultRunLoopMode)
        self.timer.fire()

    def sync_(self, notification):
        print "sync"

    def tick_(self, notification):
        print self.state


if __name__ == "__main__":
    app = NSApplication.sharedApplication()
    delegate = MyApplicationAppDelegate.alloc().init()
    app.setDelegate_(delegate)
    AppHelper.runEventLoop()
逆夏时光 2024-07-12 21:20:06

我必须这样做才能使其正常工作:

  1. 打开 MainMenu.xib。 确保应用程序委托的类是MyApplicationAppDelegate。 我不确定你是否必须这样做,但我做到了。 这是错误的,因此应用程序委托从一开始就没有被调用。

  2. 添加 statusItem.retain() 因为它会立即自动释放。

I had to do this to make it work:

  1. Open MainMenu.xib. Make sure the class of the app delegate is MyApplicationAppDelegate. I'm not sure if you will have to do this, but I did. It was wrong and so the app delegate never got called in the first place.

  2. Add statusItem.retain() because it gets autoreleased right away.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文