0

ユーザーがドックメニューで「終了」を押したときを検出する必要があります。

私のアプリケーションは、実際には Web インターフェイスのバックエンド サーバーのランチャーにすぎません。起動されたプロセスが終了するのを手動で待機して(ポーリングとスリープを使用して)、ドックメニューに保持します。アクティビティ モニターが応答していないことを示したので、「タッチ」などのイベントを処理するネイティブ関数を追加しました。応答なしフラグはなくなりましたが、ユーザーはこのアプリケーションを終了できません (ネイティブ関数がイベントを処理するためだと思います)。

そのネイティブ関数にアクセスするために ctypes を使用しました。

TVB = subprocess.popen(args)
coreFoundation = cdll.LoadLibrary('/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation')

CFRunLoopRunInMode = coreFoundation.CFRunLoopRunInMode                  # the native function
CFRunLoopRunInMode.restype = c_int32                                    # its return type
CFRunLoopRunInMode.argtypes = [ c_void_p, c_double, c_bool ]            # its arguments types

defaultMode = c_void_p.in_dll(coreFoundation, u'kCFRunLoopDefaultMode') # the default mode to process events
sleepTime = c_double(5)                                                 # the duration to process the events
retAfterSourceHandled = c_bool(0)                                       # do NOT return after processing

while not TVB.poll():                                                   # keep alive as long as TVB is alive
    CFRunLoopRunInMode(defaultMode, sleepTime, retAfterSourceHandled)
    sleep(5)
    #detect 'quit' here and stop TVB, then quit

他の解決策も検討しCFRunLoopRunInModeます...のようなものprocessNextEvent()が理想的です。

4

1 に答える 1

2

この問題の可能な解決策は、PyObjCとカスタムUIApplicationDelegate実装を使用することです。

    import AppKit
    import Foundation
    from PyObjCTools import AppHelper

    class ApplicationDelegate(Foundation.NSObject):
        """ MAC OS UI specific Delegate class """

        def applicationDidFinishLaunching_(self, notification):
            """ Here you could register a timer to pull your sub-processes, for example. """
            pass

        def applicationWillTerminate_(self, notification):
            """ This is the hook you get for when the user clicks QUIT in dock """
            pass

    app = AppKit.NSApplication.sharedApplication()
    delegate = ApplicationDelegate.alloc().init()
    app.setDelegate_(delegate)
    AppHelper.runEventLoop()

最終的に、PyObjC は試した ctypes ロードと大差ありませんが、Python コードをより明確にするヘルパー メソッド (AppKit.NSRunLoop.currentRunLoop() や AppHelper.stopEventLoop() など) がいくつかあります。

このソリューションでは、py2app を使用して展開するために Python プロジェクトをさらにパックすることを想定しています。私は pyObjc バージョン 2.3 を使用しました (Mac OS x 10.7.5 上の Python 2.7 に easy_install でインストールされています)。

于 2013-10-01T12:25:54.897 に答える