Cocoa 如何:显示复选标记、禁用菜单项、刷新菜单栏

Cocoa 如何:显示复选标记、禁用菜单项、刷新菜单栏,cocoa,menu,applescript,nsmenuitem,applescript-objc,Cocoa,Menu,Applescript,Nsmenuitem,Applescript Objc,我试图在Mac上使用带有applescript的菜单栏/状态脚本设置一些简单的服务。 在上下阅读了web之后,请记住我对脚本还不熟悉,似乎我已经达到了极限,我需要一些帮助 首先,我想在条件的菜单项旁边显示一个复选标记。在我的示例中,条件是显示分辨率介于720p和1080p之间 我根据现有脚本(其中一些我不完全理解)设置了菜单栏,如下所示: use AppleScript version "2.7" use scripting additions use framework "Foundation

我试图在Mac上使用带有applescript的菜单栏/状态脚本设置一些简单的服务。 在上下阅读了web之后,请记住我对脚本还不熟悉,似乎我已经达到了极限,我需要一些帮助

首先,我想在条件的菜单项旁边显示一个复选标记。在我的示例中,条件是显示分辨率介于720p和1080p之间

我根据现有脚本(其中一些我不完全理解)设置了菜单栏,如下所示:

use AppleScript version "2.7"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property aStatusItem : missing value

on init()
        set aBar to {"Reset Display", "1080p", "720p", "Open Monitor Preferences...", "", "External Monitor: active", "Quit"}
        set aStatusItem to current application's NSStatusBar's systemStatusBar()'s statusItemWithLength:(current application's NSVariableStatusItemLength)
        aStatusItem's setTitle:"FTV"
        aStatusItem's setHighlightMode:true
        aStatusItem's setMenu:(createMenu(aBar) of me)

    end init

    on createMenu(aList)
        set myDisplay to ChkDisplay()
        set aMenu to current application's NSMenu's alloc()'s init()
        set aCount to 1
        repeat with i in aList
            set j to contents of i
            if j is not equal to "" then
                set aMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:j action:"actionHandler:" keyEquivalent:"")
            else

                set aMenuItem to (current application's NSMenuItem's separatorItem())
            end if
            if j = myDisplay then (aMenuItem's setState:NSOnState)
            (aMenuItem's setTarget:me)
            (aMenuItem's setTag:aCount)
            (aMenu's addItem:aMenuItem)
            if j is not equal to "" then set aCount to aCount + 1
        end repeat
        return aMenu
    end createMenu
用于检查显示分辨率的处理程序:

    on ChkDisplay()
    tell application "System Preferences"
        reveal anchor "displaysDisplayTab" of pane id "com.apple.preference.displays"
    end tell
    tell application "System Events"
        set myDisplay to "720p"
        tell table 1 of scroll area 1 of tab group 1 of window "Philips FTV" of process "System Preferences"
            if selected of row 1 then set myDisplay to "1080p"
        end tell
    end tell
    tell application "System Preferences" to quit
    return myDisplay
end ChkDisplay
基本上,我希望复选标记从720p移动到1080p,这取决于哪个分辨率处于活动状态。如果单击720p和1080p项,也将设置显示分辨率

我的代码返回一个错误:NSOnState未定义。。。在那里我迷路了

我的第二个问题是找到一种方法: a) “灰显”(禁用)菜单项(在本例中为“外部监视器:活动”项) b) 在某个条件下将项目更改为“外部监视器:缺失”

我尝试了:NSMenuItem highlight:false和NSMenuItem enabled:false,并返回和出错。 此外,我不知道如何刷新菜单和/或菜单项

任何帮助或指点都将不胜感激。 我提前感谢任何人,感谢他花时间在我思考这些问题上

最终解决方案

对于问题#1,在菜单项旁边显示复选标记,多亏了@CJK help,我找到了一些工作代码:

如果j=myDisplay,则替换
(aMenuItem的setState:NSOnState)

if j = myDisplay then (aMenuItem's setState:1)

我还可以用NSimage在菜单项旁边显示任何图像(如果需要,请随时询问我)

关于问题2,启用/禁用菜单项,我还发现了一个工作代码:

在createMenu(aList)处理程序中,需要在repeat循环之前添加第二行:

set aMenu to current application's NSMenu's alloc()'s init()
aMenu's setAutoenablesItems:false
然后在重复循环中,要启用/禁用菜单项:

(aMenuItem's setEnabled:false)

**最后,要刷新菜单项,**我将代码
aMenu的removeAllItems()
放在createMenu(aList)处理程序中,并在需要刷新时调用该处理程序。似乎通过在脚本开始时删除on run/end run,一切都正常

不要在多个SE站点上交叉发布相同的问题!我可以为您解决第一个问题:
nson状态
应该是
(当前应用程序的nson状态)
。此外,请阅读Obj-C中与NSMenuItem的enabled属性相关的开发人员文档。具体地说:除非将要添加该项或该项已经是其一部分的菜单已发送,否则此属性无效
setAutoenablesItems:no
。我觉得开发者文档非常好。你能告诉我这里到底发生了什么吗?这个问题非常令人困惑,读了几遍之后,我仍然不清楚您是在创建自己的应用程序,还是在尝试控制另一个应用程序,或者脚本应该做什么(好的,我大致知道,已经读过了,但这里还有下一个要了解的上下文,所以我不知道您在做什么)。另外,任何人都很难在系统上测试
ChkDisplay
处理程序,因为它们可能有不同的显示选项。720p/1800p甚至都没有列在我的名单上…@CJK,非常感谢你的帮助。再次仔细阅读
如果j=myDisplay,则(aMenuItem的setState:(当前应用程序的NSOnState))
会在所需菜单项旁边打上un复选标记!为了回复您的第二条评论,我正在制作自己的应用程序来切换连接到Mac mini的外部监视器:因此,您说ChkDisplay处理程序非常具体是对的。我想禁用菜单中的一项,因为它只用于显示信息,但不可单击,最后在显示发生变化时(分辨率或其他)刷新我的菜单栏,它的工作方式甚至比
(当前应用程序的nson状态)
更平滑,因此如果j=myDisplay,那么代码位就是
(aMenuItem的setState:1)
。我现在正在处理启用/禁用位。再次感谢!
(aMenuItem's setEnabled:false)