python macos gui开发_Python如何在macosx上用GUI应用程序生成守护进程?

好吧,各位,有一个好的,好的和正确的解决方案,没有任何混乱。在

首先,我想解释为什么Windows GUI进程在wx.Frame.Show公司(MyFrame,False)被调用。在

非常简短的解释和略过细节的是,Windows认为窗口和应用程序是一样的。在

也就是说,MS Windows应用程序的主要元素是主GUI窗口。在

所以,当这个窗口被隐藏时,应用程序就不再有GUI,而是继续在后台运行。在

macosx将应用程序视为您的应用程序,可以说,您选择放入其中的任何窗口都是它的子级。在

这允许您在运行应用程序时不显示窗口,而只显示一个菜单栏,您可以从中选择一个操作,然后生成所需的窗口。在

非常方便的编辑器,你可能有多个文件打开一次,每一个在自己的窗口,当你关闭最后一个,你仍然可以打开一个新的或创建一个空白的,等等

因此,macosx应用程序的一个主要元素就是应用程序本身,这就是为什么它在最后一个窗口被隐藏之后仍然保持打开状态。破坏菜单栏也无济于事。应用程序的名称将保留在Dock和应用程序切换器中,并有效退出。你可以切换到它而什么也不做。:天

但是,幸运的是,Mac提供了一个将其放到后台的功能。这个函数已经在NSApp对象中提到过setApplicationActivationPolicy()。在

问题在于它在Python的AppKit中的命名NSApp.setActivationPolicy_(). 更复杂的是,它不能直接从Python的交互式shell获得,但至少必须从导入的模块调用它。在

为什么?我不知道。不管怎样,这里有一个完整的例子来说明如何把一个可以在Mac和Windows上运行的应用程序放到后台。在

我没有在Linux上尝试过,Linux结合了Mac和Windows的行为来呈现一个应用程序,所以,是否只隐藏一个窗口就足够了,还有待观察。在

请随意尝试并提交一个编辑,使示例更加跨平台。在

示例:"""

This app will show you small window with the randomly generated code that will confirm that reopened window is still the same app returned from background,

and the button allowing you to send it to background.

After you send it to background, wait 8 seconds and application will return to foreground again.

Too prove that the application is continuing its work in the background, the app will call wx.Bell() every second.

You should hear the sound while app is in the foreground and when it is in background too.

Merry Christmas and a happy New Year!

"""

import wx

import random, sys

if sys.platform=="darwin":

from AppKit import NSBundle, NSApp, NSAutoreleasePool, NSApplicationActivationPolicyRegular, NSApplicationActivationPolicyProhibited

# Use Info.plist values to know whether our process started as daemon

# Also, change this dict in case anyone is later checking it (e.g. some module)

# Note: Changing this dict doesn't change Info.plist file

info = NSBundle.mainBundle().infoDictionary()

def SendToBackground ():

# Change info, just in case someone checks it later

info["LSUIElement"] = "1"

NSApp.setActivationPolicy_(NSApplicationActivationPolicyProhibited)

def ReturnToForeground ():

# Change info, just in case someone checks it later

info["LSUIElement"] = "0"

NSApp.setActivationPolicy_(NSApplicationActivationPolicyRegular)

else:

# Simulate Mac OS X App - Info.plist

info = {"LSUIElement": "0"} # Assume non background at startup

# If programmer chose not to display GUI at startup then she/he should change this before calling ReturnToForeground()

# To preserve consistency and allow correct IsDaemon() answer

def SendToBackground ():

info["LSUIElement"] = "1"

def ReturnToForeground ():

info["LSUIElement"] = "0"

def IsDaemon ():

return info["LSUIElement"]=="1"

class Interface (wx.Frame):

def __init__ (self):

wx.Frame.__init__(self, None, -1, "Test", pos=(100, 100), size=(100, 100))

wx.StaticText(self, -1, "Test code: "+str(random.randint(1000, 10000)), pos=(10, 10), size=(80, 20))

b = wx.Button(self, -1, "DAEMONIZE ME", size=(80, 20), pos=(10, 50))

wx.EVT_BUTTON(self, b.GetId(), self.OnDaemonize)

self.belltimer = wx.Timer(self)

wx.EVT_TIMER(self, self.belltimer.GetId(), self.OnBellTimer)

self.belltimer.Start(1000)

# On Mac OS X, you wouldn't be able to quit the app without the menu bar:

if sys.platform=="darwin":

self.SetMenuBar(wx.MenuBar())

self.Show()

def OnBellTimer (self, e):

wx.Bell()

def OnDaemonize (self, e):

self.Show(False)

SendToBackground()

self.timer = wx.Timer(self)

wx.EVT_TIMER(self, self.timer.GetId(), self.OnExorcize)

self.timer.Start(8000)

def OnExorcize (self, e):

self.timer.Stop()

ReturnToForeground()

self.Show()

self.Raise()

app = wx.App()

i = Interface()

app.MainLoop()

当然,这个例子可以从终端或CLI窗口启动。在这种情况下,终端控制你的程序将保持打开,而应用程序只会出现和消失。在

要完成GUI守护进程,应该使用pythonw(在Windows上)启动它,或者从戴蒙特斯皮尤文件

在Mac上,您应该使用:

^{pr2}$

或者将其与py2app捆绑在一起,或者使用附带的Python启动器python.org网站要启动的Python版本daemontest.py公司没有终端。在

注意:这个例子在macosx上有同样的缺陷,我在问题中提供的链接中也提到了这个缺陷。我指的是当应用程序来自后台时,错误的对焦和菜单栏不立即出现的问题。用户必须切换并返回到新返回的应用程序才能正常工作。我希望有人也能解决这个问题。很快。这很烦人。在

还有一个注意事项:如果您的程序中有线程在运行,请在守护进程和排除线程时暂停它们。尤其是如果他们正在使用苹果事件与另一个应用程序通信。坦白说,关于wx计时器也应该这样做。如果您不小心,可能会在程序终止时在不存在的NSAutoreleasePool和/或SegmentationFault周围出现泄漏问题。在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值