开发者

How to switch to a python subprocess created by IPython (on OS X)?

When I use IPython along with the -wthread option, it spawns a python subprocess, which appears as a Mac OS X application.

My problem is that when I send commands to that application (for example plotting with matplotlib), the window is updated behind all my other windows. I would like to be able to call a python command to switch this python window to the front (I do that manually with ⌘-tab, but I have to find the python application first, and there might be several ones).

Is there a python script to detect which application IPython has spawned, and how to then automatically switch to it in OS X?

(I'm stating the problem in OS X, but the issue should be similar on other systems).

Edit: let me break this down in two problems:

  1. how to know which Mac OS X application python is running in? (probably possible with some IPython witchery)
  2. how to tell Mac OS X t开发者_运维问答o put the focus on that application? (maybe using applescript)


Could be either:

  1. Making a new python script that tracks grandchild processes of another script might be tricky. The IPython documentation has an example to monitor spawned processes by pid; JobControl. JobControl only kills the processes but I imagine adding a command to change window focus would be fairly easy.

  2. From what I've read, the Tk gui does not properly set window focus on macs. If your 'matplotlib' or otherwise uses the Tk gui, this may be the problem. -source-

I am not very familiar with OS X, so either run with those, clarify your situation or let me know if I'm too far off.


Here is my full solution, with an IPython magic function.

Install appscript (see this question about switching apps programmatically in OS X), and put the following code in a script called activate.py in your ~/.ipython folder.

import appscript
import sys
appscript.app(pid=int(sys.argv[1])).activate()

Now, edit your ~/.ipython/ipy_user_conf.py configuration file and define the magic function:

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)])

Now you just have to register this magic IPython function by putting the following somewhere in that same configuration file:

ip.expose_magic('wxactivate', wxactivate)

Now, after you run IPython -wthread, you can call %wxactivate and you will switch to the corresponding Python application!

(note that the reason why one has to run the call to appscript's activate() in another process in not clear to me; it may have to do with some threading problem... any explanation would be appreciatated)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜