如何切换到由IPython创建的Python子进程(在OS X上)?

1 投票
2 回答
870 浏览
提问于 2025-04-15 19:15

当我使用 IPython 并加上 -wthread 这个选项时,它会启动一个 Python 的子进程,这个进程会显示成一个 Mac OS X 的应用程序。

我遇到的问题是,当我给这个应用程序发送命令(比如用 matplotlib 绘图)时,窗口总是更新在其他窗口的后面。我希望能通过一个 Python 命令把这个窗口切换到最前面(我现在是手动用 ⌘-tab 切换,但我得先找到那个 Python 应用,而且可能有好几个)。

有没有 Python 脚本可以检测 IPython 启动了哪个应用程序,然后自动切换到这个应用程序上呢?

(我在这里说的是 OS X 的问题,但在其他系统上应该也差不多)。

补充一下:让我把这个问题分成两个部分:

  1. 如何知道 Python 运行在哪个 Mac OS X 应用程序里?(可能可以通过一些 IPython 的技巧来实现)
  2. 如何告诉 Mac OS X 把焦点放到那个应用程序上?(也许可以用 applescript 来实现)

2 个回答

1

可能是以下几种情况:

  1. 创建一个新的Python脚本来跟踪另一个脚本的子进程可能会有点复杂。IPython的文档里有一个例子,可以通过进程ID来监控生成的进程;这个例子叫做JobControl。JobControl只能结束进程,但我想如果加一个命令来改变窗口焦点应该也不难。

  2. 根据我看到的,Tk图形界面在Mac上并不能正确设置窗口焦点。如果你的'matplotlib'或者其他东西使用了Tk图形界面,这可能就是问题所在。-来源-

我对OS X不是很熟悉,所以要么你可以试试这些方法,要么给我更详细的信息,或者告诉我我是不是理解错了。

1

这是我的完整解决方案,里面用到了一个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()的调用中使用另一个进程;这可能和某些线程问题有关……如果有人能解释一下,我会很感激)

撰写回答