[英]Tkinter main window focus
我有以下代码
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()
不起作用,但上述方法起作用了。
Windows 的解决方案有点棘手 - 你不能只是从另一个窗口窃取焦点,你应该以某种方式将你的应用程序移到前台。 但首先,我建议您使用一点 windows 理论,以便我们能够确认,这就是我们想要实现的目标。
正如我在评论中提到的 - 这是使用SetForegroundWindow函数的好机会(也请检查限制!)。 但是将此类东西视为廉价黑客,因为用户“拥有”前景,而 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()
一些链接和示例:
不确定您面临什么问题。 但下面是对我很有用的示例代码。
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 测试的。
结果是,运行程序后,我可以开始输入,他输入会转到第一个文本框
注意:这是 Windows 特定的。 这将聚焦整个主窗口。 实质上是强制 alt-tab 到达窗口。
这些答案都不适合我, tk
窗口将出现在所有带有-topmost
标志的顶部,我的输入框将具有焦点,但窗口本身不会,这意味着输入不会出现在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")
当您打开-a 一个已经打开的应用程序时,该应用程序将被关注。
对于 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.