我有以下代码
window = Tk()
window.lift()
window.attributes("-topmost", True)
这段代码能够显示我的Tkinter窗口在其他所有窗口的上面,但它只解决了问题的一半。虽然窗口确实显示在其他所有窗口的上面,但是它并没有获得焦点。有没有办法让窗口不仅成为Tkinter中最前面的窗口,还能将焦点放在它上面?
如果focus_force()
不起作用,你可以尝试执行以下操作:
window.after(1, lambda: window.focus_force())
本质上是同一件事,只是用不同的方式书写而已。 我刚在Python 2.7上测试过它。
root.focus_force()
不能工作,但上述方法可以。
window.focus_force()
,window.wm_attributes("-topmost" , -1)
以及你提供的答案window.after(1, lambda : window.focus_force())
。在这三种方式中,当我运行程序时,窗口确实会立即获得焦点,但是它自己会在1秒后最小化(我既没有点击任何地方,也没有将其最小化)。为什么?我使用的是Windows 8。 - Nancy在Windows上的解决方案有些棘手 - 你不能仅仅从另一个窗口夺取焦点,你应该以某种方式将你的应用程序移至前台。但是首先,我建议您消化一下一点点的Windows理论,这样我们就能确认我们要实现的目标。
正如我在评论中提到的一样 - 这是使用SetForegroundWindow函数的好机会(也要检查限制!)。但是请考虑这样的东西是一种廉价的hack,因为用户“拥有”前台,而Windows会尽全力阻止你:
当用户正在使用另一个窗口时,应用程序无法强制将窗口置于前景。相反,Windows会闪烁窗口的任务栏按钮以通知用户。
此外,请查看此页面上的注释:
如果用户按下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()
一些链接和例子:
steal_focus
,则有可能。无论如何,keybd_event
早已被取代,因此也许您应该围绕最新的SendInput
构建解决方案,但我无法重现您所描述的行为。 - CommonSense不确定您面临的问题是什么。但是以下是我使用过的示例代码,效果非常好。
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()
这是在Windows 10上使用最新的Python 3.6进行测试的。
运行程序后,结果是我只需开始键入,输入就会进入第一个文本框。
-topmost
标志时,tk
窗口会出现在所有东西的顶部,我的输入框会获得焦点,但窗口本身不会,这意味着在tk
窗口中无法输入。它看起来像这样:
添加一个调用Windows API来窃取焦点有所帮助:import win32gui
root = tk.Tk()
# Application specific setup ...
win32gui.SetForegroundWindow(root.winfo_id())
免责声明:窃取焦点是不良行为,所以只有在必要时并且有意义时才使用它,例如对于用户将立即输入的输入框。
对我而言有效。我正在使用Macos Mojave,Python 3.6.4。在root.mainloop()之前放置此代码即可。
import os
os.system("open -a Python")
对于Linux(Ubuntu 16.04.6 LTS),我尝试了许多建议,包括使用.grab,但这会导致问题。最终,我使用了以下方法:
if self.top2_is_active is True: # Are we already playing songs?
self.top2.focus_force() # Get focus
self.top2.lift() # Raise in stacking order
root.update()
return # Don't want to start playing again
这并不是真正的“窃取”焦点,因为我在主窗口上定义了一个按钮:
''' ▶ Play Button '''
self.play_text="▶ Play" # play songs window is opened.
self.listbox_btn2 = tk.Button(frame3, text=self.play_text, \
width=BTN_WID, command=self.play_items)
self.listbox_btn2.grid(row=0, column=1, padx=2)
点击此按钮后,文本将更改为:
self.listbox_btn2 ["text"] = " Show playing" # Play button
focus_force
吗? - Bryan Oakley