【问题标题】:Problem with date picker showing (main thread issue?)日期选择器显示问题(主线程问题?)
【发布时间】:2019-10-06 13:23:41
【问题描述】:

使用来自https://github.com/bat-tomr/dialog-node 的 AppleScript 文件 ...

# 06/04/16 09:35:02
# Author: Shane Stanley
# Adapted by Christopher Stone

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

my datePicker()

on datePicker()
    set theApp to path to frontmost application as text

    if not (current application's NSThread's isMainThread()) as boolean then
        display alert "This script must be run from the main thread." buttons {"Cancel"} as critical
        error number -128
    end if
    -- create a view
    set theView to current application's NSView's alloc()'s initWithFrame:(current application's NSMakeRect(0, 0, 100, 175))
    -- create date picker
    set datePicker to current application's NSDatePicker's alloc()'s initWithFrame:(current application's NSMakeRect(0, 0, 100, 100))
    -- set style: choices are NSTextFieldAndStepperDatePickerStyle, NSClockAndCalendarDatePickerStyle, or NSTextFieldDatePickerStyle
    #datePicker's setDatePickerStyle:(current application's NSClockAndCalendarDatePickerStyle)
    datePicker's setDatePickerStyle:(current application's NSTextFieldAndStepperDatePickerStyle)
    #datePicker's setDatePickerStyle:(current application's NSTextFieldDatePickerStyle)
    -- set elements: choices include NSHourMinuteDatePickerElementFlag, NSHourMinuteSecondDatePickerElementFlag, NSTimeZoneDatePickerElementFlag, NSYearMonthDatePickerElementFlag, and NSEraDatePickerElementFlag
    datePicker's setDatePickerElements:((current application's NSYearMonthDayDatePickerElementFlag) + (current application's NSHourMinuteSecondDatePickerElementFlag as integer))

    -- set initial date
    #datePicker's setDateValue:(current application's NSDate's |date|())
    --set theCal var to a new(empty) instance of the calendar
    set theCal to current application's class "NSCalendar"'s currentCalendar()
    -- unpack the components of theCal to a variable
    set theComponents to theCal's components:254 fromDate:(current application's NSDate's |date|())
    theComponents's setSecond:0
    theComponents's setMinute:0
    theComponents's setHour:12
    theComponents's setYear:2015
    theComponents's setMonth:4
    theComponents's setDay:1
    datePicker's setDateValue:(theCal's dateFromComponents:theComponents)

    -- get the size it needs
    set theSize to datePicker's fittingSize()
    --resize the picker and view accordingly
    theView's setFrameSize:theSize
    datePicker's setFrameSize:theSize
    -- add the picker to the view
    theView's setSubviews:{datePicker}
    -- create an alert
    set theAlert to current application's NSAlert's alloc()'s init()
    -- set up alert
    tell theAlert
        its setMessageText:"Pick a date and time"
        its setInformativeText:"Any date"
        its addButtonWithTitle:"OK"
        its addButtonWithTitle:"Cancel"
        its setAccessoryView:theView
    end tell

    -- show alert in modal loop
    set returnCode to theAlert's runModal()
    if returnCode = (current application's NSAlertSecondButtonReturn) then error number -128
    -- retrieve date
    #set theDate to datePicker's dateValue() as date
    # Shane Stanley
    # http://macscripter.net/viewtopic.php?pid=119633#p119633
    set theDate to datePicker's dateValue()
    #set theCal to current application's class "NSCalendar"'s currentCalendar()
    -- unpack the components of theDate to a variable
    set theComponents to theCal's components:254 fromDate:theDate
    set theDate to current date
    set day of theDate to 1 -- important
    set seconds of theDate to theComponents's |second|()
    set year of theDate to theComponents's |year|()
    set month of theDate to theComponents's |month|()
    set day of theDate to theComponents's |day|()
    set hours of theDate to theComponents's hour()
    set minutes of theDate to theComponents's minute()

    return (theDate as text)
    #return (theDate)
end datePicker

日期选择器不显示(至少在 Mojave 上)。但是,如果我在runModal 之前放置一个display alert,它确实会显示(但不是这样)。

我知道这可能与在以后的 Mac OSX 版本中需要 performSelectorOnMainThread 有关,但如果是这种情况,我无法添加它以使代码正常工作。有什么想法吗?

【问题讨论】:

    标签: applescript applescript-objc nsalert nsdatepicker


    【解决方案1】:

    给你……真的没什么好说的。我基本上只是重写它,因为我无法忍受乱码:

    # 06/04/16 09:35:02
    # Author: Shane Stanley
    # Adapted by Christopher Stone
    # Fixed & Rewritten by CJK
    --------------------------------------------------------------------------------
    use framework "AppKit"
    use scripting additions
    
    property this : a reference to the current application
    property nil : a reference to missing value
    property _1 : a reference to reference
    
    property NSAlert : a reference to NSAlert of this
    property NSDatePicker : a reference to NSDatePicker of this
    property NSView : a reference to NSView of this
    
    property NSAlertSecondButtonReturn : 1001
    property NSHourMinuteSecondDatePickerElementFlag : 14
    property NSTextFieldAndStepperDatePickerStyle : 0
    property NSYearMonthDayDatePickerElementFlag : 224
    --------------------------------------------------------------------------------
    property date : missing value
    --------------------------------------------------------------------------------
    on run
        its performSelectorOnMainThread:("showDatePicker:") withObject:{¬
            NSTextFieldAndStepperDatePickerStyle, ¬
            NSYearMonthDayDatePickerElementFlag + ¬
            NSHourMinuteSecondDatePickerElementFlag} ¬
            waitUntilDone:true
    
        return my date
    end run
    
    on showDatePicker:params
        local params
    
        set {PickerStyle, PickerElements} to params
    
        tell (current date) to set ¬
            [dateFrom, day, its month, day, year, time] to ¬
            [it, 1, 4, 1, 2015, 12 * hours + 0 * minutes]
    
        tell NSDatePicker's alloc()
            initWithFrame_({{0, 0}, {100, 100}})
            setDatePickerStyle_(PickerStyle)
            setDatePickerElements_(PickerElements)
            setDateValue_(dateFrom)
            set fittingSize to fittingSize()
            setFrameSize_(fittingSize)
    
            set View to NSView's alloc()
            View's initWithFrame:{{0, 0}, {100, 175}}
            View's setFrameSize:fittingSize
            View's addSubview:it
    
            tell NSAlert's alloc()
                init()
                setMessageText_("Pick a date and time")
                setInformativeText_("Any date")
                addButtonWithTitle_("OK")
                addButtonWithTitle_("Cancel")
                setAccessoryView_(View)
    
                runModal()
            end tell
    
            set my date to dateValue() as date
        end tell
    end showDatePicker:
    ---------------------------------------------------------------------------❮END❯
    

    系统信息: AppleScript 版本: 2.7 系统版本: 10.13.6

    【讨论】:

    • 这看起来很棒,谢谢,我看到它从脚本编辑器运行。我渴望将它与旧版本进行比较。但首先——我可以问一下——你知道为什么当我从终端对这个文件使用osascript datepicker.scpt 时它不会运行吗?
    • 我已经将终端添加到系统偏好设置辅助功能以及 chmod 0755 和 #!/usr/bin/osascript shebang,正如我在其他地方看到的那样,这些也不起作用
    • 我相信这种脚本需要一个 GUI 上下文来运行,以便能够绘制窗口、图形上下文和视图。这意味着任何使用osascript 执行其AppleScripts 的程序也将无法对包含NSWindowNSViewWKWebView 和类似对象类的脚本执行很多操作,即使这些程序在图形用户界面。您基本上只能使用 Script EditorScript DebuggerFastScripts,或者创建自己的 AppleScript 环境。
    • 我想要一个 Node 脚本来生成 Applescript 并获取日期。看起来我可以在使用 Automator 使用此 AppleScript 制作工作流程后执行 /usr/bin/automator datepicker.workflow。看起来我什至可以拥有(如 krypted.com/mac-os-x/invoking-automator-workflows-command-line 所观察到的)一个从 Applescript 文件构建 Automator 脚本的工作流。作为开源代码,我只想让构建过程可重复且透明。
    • 不错的发现,回复:Automator。而且,是的,我对共享代码感到满意。我将我的一些代码在同一个许可证下放在了 GitHub 上,所以可以使用它是件好事。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 2011-10-20
    • 1970-01-01
    相关资源
    最近更新 更多