Distuils:创建在启动wx应用程序时不会“阻止”控制台的脚本

时间:2012-10-05 15:15:56

标签: python wxpython distutils

在我的setup.py中,我定义了一个这样的入口点:

entry_points={
      'console_scripts' : [
            'cofo = cofo:gui_main'
      ]
},

调用python setup.py develop按预期生成cofo脚本。但gui_main启动了一个wxWindows应用程序,我想" free"之后是控制台。我怎样才能做到这一点?如果我使用gui_scripts代替console_scripts,则无法发挥作用。

更新

随着"免费"控制台,我的意思是我想从命令提示符启动脚本(即将命令行参数传递给它),但是希望在gui启动后可以使用命令提示符。像这样:

Last login: Mon Oct  8 15:34:28 on ttys002
localhost:~ domma$ cofo some arguments
... gui starts and after that ...
localhost:~ domma$ 

目前我没有得到等待提示,因为脚本正在运行并且"阻止"命令行。我的主要平台是OS X,但我对一般解决方案感兴趣。

3 个答案:

答案 0 :(得分:2)

使用linux / unix(包括Mac OS X)shell,你可以运行一个命令,并通过用“&”后缀来告诉它去后台。例如:

$ cofo some arguments &

这是一个包含一些额外信息的页面:http://www.bsdguides.org/guides/netbsd/beginners/job_control/print

我建议只是通过manaully使用它/教育你的用户使用它(如果他们已经使用了一个cli,那么这不是很多问题。)如果你真的希望你的命令默认去后台,您可以使用使用上述方法的小型bash脚本包装脚本。

答案 1 :(得分:0)

以下最小示例适用于使用Windows 7 32位,Python 2.7.1,wx 2.8.12.2(msw-unicode)。调用python setup.py develop时,分别为控制台和GUI脚本生成cofo.execofogui.exe

执行cofogui.exe时,不会出现控制台窗口(这是“免费”控制台的意思吗?)

此示例使用distutils的{​​{3}}增强功能。

setup.py:

#!/usr/bin/env python

from setuptools import setup

setup(name='cofo',
      packages=['cofo'],
      entry_points={
          'console_scripts' : [
              'cofo = cofo:gui_main'
              ],
          'gui_scripts' : [
              'cofogui = cofo:gui_main'
              ]
          }
      )

cofo/__init__.py:

#!/usr/bin/env python

import wx

def gui_main():
    app = wx.App(False)  # Create a new app, don't redirect stdout/stderr to a window.
    frame = wx.Frame(None, wx.ID_ANY, "Hello World") # A Frame is a top-level window.
    frame.Show(True)     # Show the frame.
    app.MainLoop()

<强>更新 基于Windows和Unix的平台在启动进程时的运行方式不同。在Unix系统上,如果应用程序要在后台继续运行,通常的过程是使用os.fork()系统调用。正如setuptools回答中所述,这可以通过编写一个为您进行后台处理的包装脚本在应用程序之外完成。

如果这必须是完全用Python的通用解决方案,那么类似下面的内容应该做你想要的:

cofo/__init__.py:

#!/usr/bin/env python

import os
import wx

def main_app():
    app = wx.App(False)  # Create a new app, don't redirect stdout/stderr to a window.
    frame = wx.Frame(None, wx.ID_ANY, "Hello World") # A Frame is a top-level window.
    frame.Show(True)     # Show the frame.
    app.MainLoop()

def gui_main():
    """Start GUI application.

    When running on Unix based platform, fork and detach so that terminal from
    which app may have been started becomes free for use.
    """
    if not hasattr(os, 'fork'):
        main_app()
    else:
        if os.fork() == 0:
            main_app()

答案 2 :(得分:0)

这是因为shell正在等待进程完成。看来你正在寻找类似守护进程的东西。为此,您可以使用os.fork()创建流程副本,然后使用sys.exit()终止主流程(父流程)。

if os.fork():
    # Finish the parent process    
    sys.exit()

# Your program starts here (child process)

请注意,此代码与distutils无关。这是你的程序,它将作为一个守护进程。