简体   繁体   English

Kivy on Raspberry:光标位于窗口之外

[英]Kivy on Raspberry: Cursor is outside of window

I am developing a GUI on my RaspberryPi 3 using Python3 and Kivy 1.11.0dev. 我正在使用Python3和Kivy 1.11.0dev在我的RaspberryPi 3上开发GUI。 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. GUI正在运行,它在启动后全屏运行(据我所知,自Kivy 1.9.x以来,无法将Kivy应用程序作为窗口运行)并且鼠标光标可见。 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  

Solution

  1. In the constructor __init__() , bind on_cursor_leave event to a callback method eg cursor_leave() . 在构造函数__init__() ,将on_cursor_leave事件绑定到回调方法,例如cursor_leave()
  2. Use Window.grab_mouse() inside cursor_leave() method. cursor_leave()方法中使用Window.grab_mouse() Please refer to example for details. 有关详细信息,请参阅示例。

Snippet 片段

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)

Window » grab_mouse() 窗口»grab_mouse()

 grab_mouse() 

Grab mouse - so won't leave window 抓住鼠标 - 所以不会离开窗口

Note 注意

This feature requires the SDL2 window provider. 此功能需要SDL2窗口提供程序。

Example

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()

Output 产量

IMG01

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? 每次调用但没有任何影响......有没有办法在离开允许区域时将光标设置回窗口?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM