在Mac OS X上,如何让Tkinter窗口获得焦点?

15

我正在使用Tkinter GUI框架编写Python应用程序。它需要监听键盘和鼠标事件,因此必须具有焦点。当它在Ubuntu终端中启动时,以下代码可以运行:

from Tkinter import *

root = Tk()
root.focus_force()

def key(event):
    print "pressed", event.char

def callback(event):
    print "clicked at", event.x, event.y 

frame = Frame(root, width=100, height=100)
frame.bind("<Key>", key)
frame.bind("<Button-1>", callback)
frame.pack()
frame.focus_force()

root.mainloop()

然而,在Mac OS X 10.8.4(默认Python 2.7.2)的终端中启动时,焦点保留在终端仿真器上,直到用户单击窗口。有人知道如何解决这个问题吗?

3个回答

15

我尝试了这个方法,对我来说很有效:

from os import system
from platform import system as platform

# set up your Tk Frame and whatnot here...

if platform() == 'Darwin':  # How Mac OS X is identified by Python
    system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')
当然,这会将整个应用程序置于前台,而不仅仅是特定的窗口,但在执行此操作后,您可以对特定的框架或窗口使用 focus_force(),并将其移到所有应用程序窗口的最前面。
对于那些感兴趣的人,我没有自己编写 system() 调用。我在SourceForge 上的这个线程 中找到了它。
我将 system() 调用放在验证此代码正在 OS X 上运行的 if 块中,这使得解决方案跨平台 - 我的理解是 focus_force() 在所有其他平台上都能正常工作,只需在 system() 调用之后立即执行它也不会在 OS X 上造成任何问题。

2

我来到这里也有同样的问题,但我从Kevin Walzer聪明的回答中发现了解决方法,他建议使用py2app

是的,这是OS X的标准行为。在终端中运行应用程序会保持焦点在终端上,除非你通过点击窗口来切换。命令-Tab的行为由窗口系统确定,而不是由新生成的进程确定。

解决方法是将你的应用程序打包成一个标准的Mac应用程序束,使用py2app。普通的Mac用户不会从命令行启动基于Python的游戏。

Kevin

(来自https://groups.google.com/forum/#!topic/comp.lang.python/ZPO8ZN5dx3M


你也可以使用 pyinstaller。我喜欢它,因为我可以制作Mac应用程序包和Windows可执行文件。 - Fiver

-1

wait_visibility 和 event_generate 有帮助吗?

例如,类似以下代码:

from Tkinter import *

root = Tk()

def key(event):
    print "pressed", event.char

def callback(event):
    print "clicked at", event.x, event.y 

frame = Frame(root, width=100, height=100)
frame.bind("<Key>", key)
frame.bind("<Button-1>", callback)
frame.pack()

frame.focus_set()

root.wait_visibility()
root.event_generate('<Button-1>', x=0, y=0)

root.mainloop()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接