Kivy: нежелательное поведение пользовательского курсора мыши при пересечении левого или верхнего края окна приложения - PullRequest
0 голосов
/ 19 декабря 2018

Я хочу сделать пользовательский курсор мыши в киве.Это то, что у меня есть на данный момент:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.scatter import Scatter
from kivy.core.window import Window
#Window.show_cursor = False

KV = """
FloatLayout
    BoxLayout
        MyTextInput
    MyMouse


<MyTextInput>:
    font_size: 40
    text: 'Some text'

<MyMouse>:
    mouse_im_size: mouse_im.size
    auto_bring_to_front: True

    do_rotation:False
    do_scale:False
    do_translation_y:False

    Image
        id: mouse_im
        size: 100, 100 / self.image_ratio
        source: 'cursor-pink.png'

"""

class MyTextInput(TextInput):
    pass

class MyMouse(Scatter):
    def __init__(self, **kwargs):
        Window.bind(mouse_pos=self.on_mouse_pos)
        super(MyMouse, self).__init__(**kwargs)

    def on_touch_down(self, *touch):
        return

    def on_mouse_pos(self, *args):
        x,y = args[1]
        self.pos = [x,y-self.mouse_im_size[1]]


class MyApp(App):
    def build(self):
        self.root = Builder.load_string(KV)

MyApp().run()

проблема в том, что когда я перемещаю мышь за левый или верхний край приложения, изображение курсора остается внутри приложения, и я хочу изображение мышиисчезнуть так же, как при перемещении мыши за правый или нижний край.

Кажется, проблема в том, что on_mouse_pos() работает только тогда, когда мышь находится внутри окна.

I нашел способ получить положение мыши, когда оно находится за пределами окна, но я не знаю, как это можно использовать в моей задаче.И, может быть, есть лучший способ сделать это.

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

Вот еще один подход, но он требует рамки вокруг вашей базовой компоновки:

from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.scatter import Scatter
from kivy.core.window import Window
#Window.show_cursor = False

KV = """
FloatLayout
    canvas.before:
        Color:
            rgba: (1, 0, 0, 1)
        Rectangle:
            size: self.size
            pos: self.pos
    FloatLayout
        id: mainlayout
        size_hint: (None, None)
        #pos: (50, 50)
        #pos_hint: {'center_x': 0.5, 'center_y': 0.5}
        canvas.before:
            Color:
                rgba: (0, 1, 0, 1)
            Rectangle:
                size: self.size
                pos: self.pos
        BoxLayout
            size_hint: (1.0, 0.2)
            pos_hint: {'center_x': 0.5, 'top': 1.0}
            MyTextInput
        StencilView:
            size_hint: (1.0, 1.0)
            pos_hint: {'x': 0, 'y': 0}
            MyMouse
                id: themouse


<MyTextInput>:
    font_size: 40
    text: 'Some text'

<MyMouse>:
    mouse_im_size: mouse_im.size
    auto_bring_to_front: True

    do_rotation:False
    do_scale:False
    do_translation_y:False

    Image
        id: mouse_im
        size: 100, 100 / self.image_ratio
        source: 'cursor-pink.png'

"""

class MyTextInput(TextInput):
    pass

class MyMouse(Scatter):
    def __init__(self, **kwargs):
        Window.bind(mouse_pos=self.on_mouse_pos)
        super(MyMouse, self).__init__(**kwargs)

    def on_touch_down(self, *touch):
        return

    def on_mouse_pos(self, *args):
        x,y = args[1]
        self.pos = [x,y-self.mouse_im_size[1]]

class MyApp(App):
    def build(self):
        self.mainlayout = None
        self.mymouse = None
        self.root = Builder.load_string(KV)
        Window.bind(size=self.do_size)
        Clock.schedule_once(self.do_size)

    def do_size(self, *args):
        if self.mainlayout is None:
            self.mainlayout = self.root.ids.mainlayout
        if self.mymouse is None:
            self.mymouse = self.root.ids.themouse

        self.mainlayout.size = (self.root.width - 2.0 * self.mymouse.mouse_im_size[0], self.root.height - 2.0 * self.mymouse.mouse_im_size[1])
        self.mainlayout.pos = self.mymouse.mouse_im_size

MyApp().run()

. Используется StencilView для обрезки чертежа курсора внутри макета man.

0 голосов
/ 19 декабря 2018

Вы можете сделать это, используя Window события on_cursor_enter и on_cursor_leave и сделав курсор видимым / невидимым, используя свойство opacity:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.scatter import Scatter
from kivy.core.window import Window
#Window.show_cursor = False

KV = """
FloatLayout
    BoxLayout
        MyTextInput
    MyMouse
        id: themouse


<MyTextInput>:
    font_size: 40
    text: 'Some text'

<MyMouse>:
    mouse_im_size: mouse_im.size
    auto_bring_to_front: True

    do_rotation:False
    do_scale:False
    do_translation_y:False

    Image
        id: mouse_im
        size: 100, 100 / self.image_ratio
        source: 'cursor-pink.png'

"""

class MyTextInput(TextInput):
    pass

class MyMouse(Scatter):
    def __init__(self, **kwargs):
        Window.bind(mouse_pos=self.on_mouse_pos)
        Window.bind(on_cursor_leave=self.on_cursor_leave)
        Window.bind(on_cursor_enter=self.on_cursor_enter)
        super(MyMouse, self).__init__(**kwargs)

    def on_touch_down(self, *touch):
        return

    def on_mouse_pos(self, *args):
        x,y = args[1]
        self.pos = [x,y-self.mouse_im_size[1]]

    def on_cursor_leave(self, *args):
        App.get_running_app().root.ids.themouse.opacity = 0

    def on_cursor_enter(self, *args):
        App.get_running_app().root.ids.themouse.opacity = 1


class MyApp(App):
    def build(self):
        self.root = Builder.load_string(KV)

MyApp().run()

Я добавил themouse id для виджета MyMouse, чтобы выполнить это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...