简体   繁体   English

Tkinter窗口专注于Mac OS X.

[英]Tkinter window focus on Mac OS X

I'm writing an application in Python with the Tkinter GUI framework. 我正在使用Tkinter GUI框架在Python中编写应用程序。 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: 当它从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()

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. 但是,当从Mac OS X 10.8.4(库存Python 2.7.2)中的终端启动时,终端仿真器会保留焦点,直到用户单击窗口。 Does anyone know of a workaround for this? 有谁知道这个的解决方法?

I tried this and it worked well for me: 我尝试了这个,它对我有用:

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

Of course, that'll bring your entire application to the front, not just a specific window, but after you do that, you can then use focus_force() on a specific frame or window and that'll get moved to become the frontmost of all your application windows. 当然,这将把你的整个应用程序放在前面,而不仅仅是一个特定的窗口,但是在你这样做之后,你可以在特定的框架或窗口上使用focus_force()并且它将被移动到最前面所有应用程序窗口。

For those interested, I didn't write the system() call myself. 对于那些感兴趣的人,我没有写自己的system() I found it in this thread on SourceForge . 在SourceForge上找到了这个帖子

The fact that I put the system() call within an if block that verifies this is running on OS X makes the solution cross platform - my understanding is that focus_force() works on all other platforms exactly as you want, and just performing it after the system() invocation wouldn't cause any problems in OS X, either. 我将system()调用放在一个if块中来验证它在OS X上运行的事实使得该解决方案跨平台 - 我的理解是focus_force()完全按照您的需要在所有其他平台上运行,并且只是在执行之后执行它system()调用也不会在OS X中引起任何问题。

came here wondering the same question, but I found this wise sounding answer from Kevin Walzer which suggests to use py2app : 来到这里想知道同样的问题,但我发现凯文沃尔泽这个明智的答案建议使用py2app

Yes, this is standard behavior for OS X. Running an app in Terminal keeps focus in the Terminal unless you switch by clicking windows. 是的,这是OS X的标准行为。在终端中运行应用程序会将焦点保留在终端中,除非您通过单击窗口进行切换。 The Command-Tab behavior is determined by the windowing system, not by a newly spawned process. Command-Tab行为由窗口系统确定,而不是由新生成的进程确定。

The way around this is to wrap your application up in a standard Mac app bundle using py2app. 解决这个问题的方法是使用py2app将应用程序包装在标准的Mac应用程序包中。 The average Mac user isn't going to launch a Python-based game from the command line. 普通的Mac用户不会从命令行启动基于Python的游戏。

Kevin 凯文

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

Do wait_visibility and event_generate help ? wait_visibility和event_generate帮助吗?

eg. 例如。 something like - 就像是 -

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM