我有以下代码
window = Tk()
window.lift()
window.attributes("-topmost", True)
此代码的作用是它在所有其他窗口上方显示我的Tkinter窗口,但它仍然只解决了一半的问题。虽然窗口实际上显示在所有其他窗口之上,但窗口没有焦点。有没有办法不仅让窗口成为Tkinter的最前面的窗口,还关注它?
答案 0 :(得分:6)
如果focus_force()
无效,您可以尝试:
window.after(1, lambda: window.focus_force())
它本质上是相同的,只是用不同的方式写的。我刚刚在python 2.7上测试过它。
root.focus_force()
不起作用,但上述方法确实有效。
答案 1 :(得分:4)
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()
一些链接和示例:
答案 2 :(得分:0)
不确定您面临的问题。但下面的示例代码对我来说很有用。
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上使用Latest Python 3.6测试的。
结果是在运行程序后,我可以开始输入,并且输入将转到第一个文本框
答案 3 :(得分:0)
注意:这是Windows特定的。这会聚焦整个主窗口。基本上强制alt-tab到达窗口。
这些答案都不适用于我,tk
窗口会显示在-topmost
标志的所有内容之上,我的输入框会有焦点,但窗口本身不会,这意味着打字不会出现在tk
窗口中。它看起来像这样:
添加对Windows API的调用有助于窃取焦点:
import win32gui
root = tk.Tk()
# Application specific setup ...
win32gui.SetForegroundWindow(root.winfo_id())
免责声明:窃取焦点是不良行为,因此只有在必要时才使用它,如果有意义,例如用户将立即输入的输入框。
答案 4 :(得分:0)
对我有用。我在Macos Mojave,python 3.6.4上。将此代码放在root.mainloop()
之前import os
os.system("open -a Python")
当您打开-a已打开的应用程序时,该应用程序将被重点关注。
答案 5 :(得分:0)
对于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