如何让我的 python-kivy window 在鼠标光标悬停在 window 上时成为焦点?
How do I make my python-kivy window become the focus when the mouse cursor is over the window?
python 3.7.8
kivy 2.0.0
现代程序能够在 window 中进行更改,即使应用程序的焦点不是 True。
示例:两个 windows 并排设置(Chrome 和 Excel)。我在 Chrome window 内部单击,它变成了焦点 True。然后,当我将光标移到 Excel window 时,我可以直接单击单元格或上下滚动。 Excel 中的此操作不需要我先单击 Excel window 使其成为焦点。
我无法用 python-kivy 复制它。
Window.on_cursor_enter(do_action())
当光标进入 window 时不触发。
def on_start(self):
Window.bind(mouse_pos=self.my_callback)
def my_callback(self, instance, value):
Window.focus = True
投掷:
File "kivy\properties.pyx", line 498, in kivy.properties.Property.__set__
File "kivy\properties.pyx", line 1527, in kivy.properties.AliasProperty.set
File "kivy\properties.pyx", line 1485, in kivy.properties.AliasProperty.__read_only
AttributeError: "WindowSDL.focus" property is readonly
更新:
Window.on_cursor_enter(do_action())
在 kivy 源代码中带有 pass
。这就解释了为什么它不起作用。
我认为真正的修正将来自对 ctypes.windll.user32
...setFocus...之类的调用
但是我是一个Python爱好者,对此理解有限
我想我找到了解决方法,但您可能不会满意。
无论如何,这是我的解决方案:
import kivy
from kivy.uix.widget import Widget
from kivy.app import App
from kivy.clock import Clock
from kivy.core.window import Window
import pyautogui # for mouse click
kivy.lang.Builder.load_string("""
#:kivy 2.0.0
<Main>:
ScrollView:
do_scroll_x: True
do_scroll_y: True
size: root.size
BoxLayout:
size_hint: 1, None
width: 50
orientation: "vertical"
Label:
text: "Hello World !"
font_size: 25
Button:
id: my_button
text: "click me !"
font_size: 25
on_release:
root.button_callback()
""")
class Main(Widget):
def button_callback(self): # fired when button is clicked
print("clicked on button !")
def window_callback(self, instance): # fired when cursor entered window
Window.restore() # seems like doesn't work
Window.show() # this also
# so I do this when the mouse is hover on the window
# import pyautogui first
if Window.focus == False:
pyautogui.click() # a mouse click for focusing the window
print(True) # just to clarify the above line got executed
print(f"window is focus ? {Window.focus}") # although it may says the windows is not focused , it should be
def update(self, dt):
Window.bind(on_cursor_enter = self.window_callback) # bind when on_cursor_enter
class MyKivyApp(App):
def build(self):
Clock.schedule_interval(Main().update, 1/60)
return Main()
if __name__ == "__main__":
MyKivyApp().run()
工作原理:当鼠标悬停在应用程序 window 上时,pyautogui
单击一次鼠标,以编程方式强制焦点到应用程序 window。
update
func 和 window_callback
func 中唯一的代码行将在鼠标悬停在 window 上时触发(即当鼠标离开并返回时到应用程序 window , window_callback
将被解雇)然后我使用 pyautogui
自己进行鼠标单击,以便 window 可以自行聚焦。这样,当鼠标移回 window.
时,kivy 应用程序 window 可以聚焦
此外,根据此 Whosebug answer ,桌面应用程序上的 SLD2 可以隐藏 window 但要恢复/显示它。即使应用程序 window 未聚焦(我测试过)它也可以滚动
python 3.7.8
kivy 2.0.0
现代程序能够在 window 中进行更改,即使应用程序的焦点不是 True。
示例:两个 windows 并排设置(Chrome 和 Excel)。我在 Chrome window 内部单击,它变成了焦点 True。然后,当我将光标移到 Excel window 时,我可以直接单击单元格或上下滚动。 Excel 中的此操作不需要我先单击 Excel window 使其成为焦点。
我无法用 python-kivy 复制它。
Window.on_cursor_enter(do_action())
当光标进入 window 时不触发。
def on_start(self):
Window.bind(mouse_pos=self.my_callback)
def my_callback(self, instance, value):
Window.focus = True
投掷:
File "kivy\properties.pyx", line 498, in kivy.properties.Property.__set__
File "kivy\properties.pyx", line 1527, in kivy.properties.AliasProperty.set
File "kivy\properties.pyx", line 1485, in kivy.properties.AliasProperty.__read_only
AttributeError: "WindowSDL.focus" property is readonly
更新:
Window.on_cursor_enter(do_action())
在 kivy 源代码中带有 pass
。这就解释了为什么它不起作用。
我认为真正的修正将来自对 ctypes.windll.user32
...setFocus...之类的调用
但是我是一个Python爱好者,对此理解有限
我想我找到了解决方法,但您可能不会满意。
无论如何,这是我的解决方案:
import kivy
from kivy.uix.widget import Widget
from kivy.app import App
from kivy.clock import Clock
from kivy.core.window import Window
import pyautogui # for mouse click
kivy.lang.Builder.load_string("""
#:kivy 2.0.0
<Main>:
ScrollView:
do_scroll_x: True
do_scroll_y: True
size: root.size
BoxLayout:
size_hint: 1, None
width: 50
orientation: "vertical"
Label:
text: "Hello World !"
font_size: 25
Button:
id: my_button
text: "click me !"
font_size: 25
on_release:
root.button_callback()
""")
class Main(Widget):
def button_callback(self): # fired when button is clicked
print("clicked on button !")
def window_callback(self, instance): # fired when cursor entered window
Window.restore() # seems like doesn't work
Window.show() # this also
# so I do this when the mouse is hover on the window
# import pyautogui first
if Window.focus == False:
pyautogui.click() # a mouse click for focusing the window
print(True) # just to clarify the above line got executed
print(f"window is focus ? {Window.focus}") # although it may says the windows is not focused , it should be
def update(self, dt):
Window.bind(on_cursor_enter = self.window_callback) # bind when on_cursor_enter
class MyKivyApp(App):
def build(self):
Clock.schedule_interval(Main().update, 1/60)
return Main()
if __name__ == "__main__":
MyKivyApp().run()
工作原理:当鼠标悬停在应用程序 window 上时,pyautogui
单击一次鼠标,以编程方式强制焦点到应用程序 window。
update
func 和 window_callback
func 中唯一的代码行将在鼠标悬停在 window 上时触发(即当鼠标离开并返回时到应用程序 window , window_callback
将被解雇)然后我使用 pyautogui
自己进行鼠标单击,以便 window 可以自行聚焦。这样,当鼠标移回 window.
此外,根据此 Whosebug answer ,桌面应用程序上的 SLD2 可以隐藏 window 但要恢复/显示它。即使应用程序 window 未聚焦(我测试过)它也可以滚动