I am developing a GUI on my RaspberryPi 3 using Python3 and Kivy 1.11.0dev. The GUI is working, it is running in fullscreen after start (as far a I know since Kivy 1.9.x it is not possible to run a Kivy app as a window) and the mouse cursor is visible. The only problem now is that the user can move the mouse out of the visible area if he goes too far to the left, right, up or down. If this happens, it is difficult to get the cursor back to the visible area.
I tried a lot to prevent that or to take the cursor back to window automatically but without success. From similar posts I tried things like this:
Window.bind(on_cursor_leave=self.on_leave)
def on_leave(self, *args):
if self.hold:
print('Cursor leaved Window')
# call api calls here
I also tried to grab the mouse
Window.bind(grab_mouse=self.on_leave)
Does anybody have a solution for putting the cursor back to the visible area after leaving or to set a border where the cursor can't leave?
EDIT: Maybe this output helps:
[INFO ] [Logger ] Record log in /home/pi/.kivy/logs/kivy_18-07-30_8.txt
[INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_pil, img_gif (img_ffpyplayer ignored)
[INFO ] [Kivy ] v1.11.0.dev0, git-0471549, 20180720
[INFO ] [Python ] v3.4.2 (default, Oct 19 2014, 13:31:11)
[GCC 4.9.1]
[INFO ] [KivyMD ] KivyMD version: 0.1.2
[INFO ] [Factory ] 194 symbols loaded
[INFO ] [Text ] Provider: sdl2
[INFO ] [Window ] Provider: egl_rpi
[INFO ] [GL ] Using the "OpenGL ES 2" graphics system
[INFO ] [GL ] Backend used <gl>
[INFO ] [GL ] OpenGL version <b'OpenGL ES 2.0'>
[INFO ] [GL ] OpenGL vendor <b'Broadcom'>
[INFO ] [GL ] OpenGL renderer <b'VideoCore IV HW'>
[INFO ] [GL ] OpenGL parsed version: 2, 0
[INFO ] [GL ] Shading version <b'OpenGL ES GLSL ES 1.00'>
[INFO ] [GL ] Texture max size <2048>
[INFO ] [GL ] Texture max units <8>
[INFO ] [Window ] virtual keyboard not allowed, single mode, not docked
[INFO ] [GL ] NPOT texture support is available
xclip version 0.12
Copyright (C) 2001-2008 Kim Saunders et al.
Distributed under the terms of the GNU GPL
[INFO ] [Clipboard ] Provider: xclip
[INFO ] [CutBuffer ] cut buffer support enabled
[INFO ] [ProbeSysfs ] device match: /dev/input/event0
[INFO ] [HIDInput ] Read event from </dev/input/event0>
[INFO ] [ProbeSysfs ] device match: /dev/input/event1
[INFO ] [HIDInput ] Read event from </dev/input/event1>
[INFO ] [Base ] Start application main loop
[INFO ] [HIDMotionEvent] using <b'MLK USB Composite Device\x00 '>
[INFO ] [HIDMotionEvent] using <b'MLK USB Composite Device\x00
__init__()
, bind on_cursor_leave
event to a callback method eg cursor_leave()
. Window.grab_mouse()
inside cursor_leave()
method. Please refer to example for details. class GrabMouseDemo(Label):
def __init__(self, **kwargs):
super(GrabMouseDemo, self).__init__(**kwargs)
Window.bind(mouse_pos=self.mouse_pos)
Window.bind(on_cursor_leave=self.cursor_leave)
grab_mouse()
Grab mouse - so won't leave window
Note
This feature requires the SDL2 window provider.
from kivy.app import App
from kivy.uix.label import Label
from kivy.core.window import Window
class GrabMouseDemo(Label):
def __init__(self, **kwargs):
super(GrabMouseDemo, self).__init__(**kwargs)
Window.bind(mouse_pos=self.mouse_pos)
Window.bind(on_cursor_leave=self.cursor_leave)
def mouse_pos(self, window, pos):
self.text = str(pos)
def cursor_leave(self, window):
print("cursor_leave:")
Window.grab_mouse()
class TestApp(App):
title = "Kivy Grab Mouse Demo"
def build(self):
return GrabMouseDemo()
if __name__ == "__main__":
TestApp().run()
Okay I solved the Problem. It's not my favorite solution but it works:
# Set mouse back to visible window when leaving 1920x1080
def mouse_pos(self, window, pos):
try:
#pos_width = int(pos[0])
#pos_height = int(pos[1])
if int(pos[0]) <= 0: # Mouse outside, LEFT
window.mouse_pos = (5, int(pos[1]))
if int(pos[0]) > self.win_width: # Mouse outside, RIGHT
window.mouse_pos = (1900, int(pos[1]))
if int(pos[1]) < 0: # Mouse outside, BOTTOM
window.mouse_pos = (int(pos[0]), 20)
if int(pos[1]) > self.win_height: # Mouse outside, TOP
window.mouse_pos = (int(pos[0]), 1060)
The cursor is moved back when he leaves the window.
At this time my approach is:
class WSRMEGUI(BoxLayout):
...
def __init__(self, **kwargs):
super(WSRMEGUI, self).__init__(**kwargs)
Window.bind(mouse_pos=self.mouse_pos)
def mouse_pos(self, window, pos):
poswidth = int(pos[0])
posheight = int(pos[1])
winwidth = int(window.width)
winheight = int(window.height)
if poswidth <= 0:
Window.grab_mouse()
if poswidth > winwidth:
Window.grab_mouse()
if posheight < 0:
Window.grab_mouse()
if posheight > winheight:
Window.grab_mouse()
So if the cursor leaves the window
Window.grab_mouse()
is called everytime but without any effect... Is there a way to set the cursor back to window when he leaves the allowed area?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.