如何切换到由IPython创建的Python子进程(在OS X上)?
当我使用 IPython 并加上 -wthread
这个选项时,它会启动一个 Python 的子进程,这个进程会显示成一个 Mac OS X 的应用程序。
我遇到的问题是,当我给这个应用程序发送命令(比如用 matplotlib
绘图)时,窗口总是更新在其他窗口的后面。我希望能通过一个 Python 命令把这个窗口切换到最前面(我现在是手动用 ⌘-tab 切换,但我得先找到那个 Python 应用,而且可能有好几个)。
有没有 Python 脚本可以检测 IPython 启动了哪个应用程序,然后自动切换到这个应用程序上呢?
(我在这里说的是 OS X 的问题,但在其他系统上应该也差不多)。
补充一下:让我把这个问题分成两个部分:
- 如何知道 Python 运行在哪个 Mac OS X 应用程序里?(可能可以通过一些 IPython 的技巧来实现)
- 如何告诉 Mac OS X 把焦点放到那个应用程序上?(也许可以用 applescript 来实现)
2 个回答
可能是以下几种情况:
创建一个新的Python脚本来跟踪另一个脚本的子进程可能会有点复杂。IPython的文档里有一个例子,可以通过进程ID来监控生成的进程;这个例子叫做JobControl。JobControl只能结束进程,但我想如果加一个命令来改变窗口焦点应该也不难。
根据我看到的,Tk图形界面在Mac上并不能正确设置窗口焦点。如果你的'matplotlib'或者其他东西使用了Tk图形界面,这可能就是问题所在。-来源-
我对OS X不是很熟悉,所以要么你可以试试这些方法,要么给我更详细的信息,或者告诉我我是不是理解错了。
这是我的完整解决方案,里面用到了一个IPython的魔法函数。
首先,你需要安装appscript(可以参考这个问题,了解如何在OS X中编程切换应用程序),然后把下面的代码放到一个名为activate.py
的脚本里,放在你的~/.ipython
文件夹中。
import appscript
import sys
appscript.app(pid=int(sys.argv[1])).activate()
接下来,编辑你的~/.ipython/ipy_user_conf.py
配置文件,定义这个魔法函数:
def wxactivate(self, arg):
import wx
pid = wx.GetProcessId()
ip = self.api
import os
here = os.path.dirname(__file__)
import subprocess
subprocess.Popen([os.path.join(here, 'activate.py'), str(pid)])
然后,你只需要在同一个配置文件里注册这个魔法IPython函数,添加以下内容:
ip.expose_magic('wxactivate', wxactivate)
现在,当你运行IPython -wthread
后,你可以调用%wxactivate
,这样就能切换到相应的Python应用程序了!
(顺便提一下,我不太明白为什么要在activate()
的调用中使用另一个进程;这可能和某些线程问题有关……如果有人能解释一下,我会很感激)