2014-03-30 175 views
6

我有以下代码Tkinter的主窗口焦点

window = Tk() 
window.lift() 
window.attributes("-topmost", True) 

此代码的工作,它上面显示所有其他窗口我Tkinter的窗口,但它仍然只是解决了问题的一半。虽然窗口实际上显示在所有其他窗口之上,但窗口没有焦点。有没有一种方法可以使窗户成为Tkinter的最前面的窗户,而且还将注意力集中在它上面?

+0

是什么让你觉得它没有重点?你有没有试过在窗口上调用'focus_force'? –

+1

我认为它没有焦点,因为窗口是灰色的,我不得不点击它来识别击键,也'focus_force'不能解决问题 –

+0

@marczellm,你能指定问题吗?我在Python 3.6和Windows 10上运行代码,它的工作原理 –

回答

4

如果focus_force()不工作,你可以尝试做:

window.after(1, lambda: window.focus_force()) 

它本质上是一样的东西,只是有不同的写法。我只是在python 2.7上测试它。

root.focus_force()不起作用,但上述方法。

+0

你使用的是什么操作系统? (我在OSX上) –

+0

@PythonSpoilsYou对不起,对于迟到的回复,但我在Windows上。我只是重新测试了这一点,它似乎只适用于一个代码,但另一个没有。 –

+0

你有什么想法为什么? –

-1

不知道你面临什么问题。但下面是适用于我的很好的示例代码。

from tkinter import * 

window = Tk() 

def handle_focus(event): 
    if event.widget == window: 
     window.focus_set() 
     input1.focus_set() 


label1 = Label(window,text = "Enter Text 2") 
input1 = Entry(window, bd=5) 

label2 = Label(window,text = "Enter Text 2") 
input2 = Entry(window, bd=5) 

submit = Button(window, text="Submit") 

label1.pack() 
input1.pack() 
label2.pack() 
input2.pack() 
submit.pack(side=BOTTOM) 

window.lift() 
window.attributes("-topmost", True) 

window.bind("<FocusIn>", handle_focus) 

hwnd = window.winfo_id() 

window.mainloop() 

这是使用最新的Python 3.6测试在Windows 10

Test Results

其结果是,运行该程序后,我可以开始输入和他的投入将进入第一文本框

+0

我想要做的是我的应用程序(响应全局键盘事件或定时事件)从其他应用程序(例如Firefox)窃取焦点。 – marczellm

+0

@marczellm,不幸的是,您的要求不是关于从另一个应用程序(至少取得胜利)窃取重点,而是关于替换一个[*前景*](https://msdn.microsoft.com/en-gb/library /windows/desktop/ms633539(v=vs.85).aspx)窗口(例如firefox)与另一个(你的tk应用程序)。这不是那么简单的任务,因为它似乎是,所以这是一个[类似的问题](https://stackoverflow.com/questions/26323767/intercepting-a-windows-attempt-to-steal-global-focus-on-视窗)。 – CommonSense

1

针对Windows的解决方案有点棘手 - 您不能仅从另一个窗口窃取焦点,您应该将应用程序以某种方式移至前台。 但首先,我建议你消费littlebit of windows theory,所以我们能够确认,这是我们想要实现的。

正如我在comment中提到的那样 - 这是使用SetForegroundWindow函数的一个好机会(也请检查限制!)。但考虑这样的东西作为一种廉价的破解,因为用户“拥有”的前景,和Windows会试图不惜一切代价阻止你:

应用程序无法强迫一个窗口到前台当用户正在与另一扇窗。相反,Windows会闪烁窗口的任务栏按钮以通知用户。

此外,检查了一句话就this页:

系统将自动启用呼叫如果用户按下ALT键或采取一些行动,导致系统本身来改变前台窗口(以SetForegroundWindow例如,点击背景窗口)。

这里是进入一个最简单的解决方案,因为我们能够效仿Alt按:

import tkinter as tk 
import ctypes 

# store some stuff for win api interaction 
set_to_foreground = ctypes.windll.user32.SetForegroundWindow 
keybd_event = ctypes.windll.user32.keybd_event 

alt_key = 0x12 
extended_key = 0x0001 
key_up = 0x0002 


def steal_focus(): 
    keybd_event(alt_key, 0, extended_key | 0, 0) 
    set_to_foreground(window.winfo_id()) 
    keybd_event(alt_key, 0, extended_key | key_up, 0) 

    entry.focus_set() 


window = tk.Tk() 

entry = tk.Entry(window) 
entry.pack() 

# after 2 seconds focus will be stolen 
window.after(2000, steal_focus) 

window.mainloop() 

一些链接和例子: