14

I'm writing an application in Python with the Tkinter GUI framework. It listens for keyboard and mouse events, so it must have focus. When it is launched from a terminal in Ubuntu, the following code works:

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

However, when launched from a terminal in Mac OS X 10.8.4 (stock Python 2.7.2), focus is retained by the terminal emulator until the user clicks on the window. Does anyone know of a workaround for this?

4

3 回答 3

14

我试过了,对我来说效果很好:

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()调用放在一个 if 块中验证它是否在 OS X 上运行的事实使解决方案跨平台 - 我的理解是它focus_force()可以在所有其他平台上完全按照你的意愿工作,并且在system()调用后执行它不会导致OS X 中的任何问题。

于 2014-09-20T03:39:58.813 回答
2

来到这里想知道同样的问题,但我发现凯文沃尔泽这个明智的回答建议使用py2app

是的,这是 OS X 的标准行为。在终端中运行应用程序会将焦点保持在终端中,除非您通过单击窗口进行切换。命令选项卡的行为由窗口系统决定,而不是由新产生的进程决定。

解决这个问题的方法是使用 py2app 将您的应用程序包装在标准的 Mac 应用程序包中。一般的 Mac 用户不会从命令行启动基于 Python 的游戏。

凯文

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

于 2013-12-07T19:08:02.127 回答
-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()
于 2013-07-23T22:15:24.820 回答