Python Kivy:自定义鼠标光标穿过应用程序窗口的左边缘或上边缘时的不良行为

Python Kivy:自定义鼠标光标穿过应用程序窗口的左边缘或上边缘时的不良行为,python,kivy,Python,Kivy,我想在kivy中制作一个自定义鼠标光标。 这就是我目前的情况: 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_c

我想在kivy中制作一个自定义鼠标光标。 这就是我目前的情况:

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()
从kivy.app导入应用
从kivy.lang导入生成器
从kivy.uix.button导入按钮
从kivy.uix.textinput导入textinput
从kivy.uix.scatter导入scatter
从kivy.core.window导入窗口
#Window.show\u cursor=False
KV=”“”
浮动布局
盒子布局
MyTextInput
老鼠
:
字体大小:40
文本:“一些文本”
:
鼠标大小:鼠标大小
自动\u将\u带到\u前端:真
do_旋转:错误
do_比例:错误
是否翻译:错误
形象
id:mouse\u im
尺寸:100,100/self.image\u比率
来源:'光标粉红色.png'
"""
类MyTextInput(TextInput):
通过
类MyMouse(分散):
定义初始(自我,**kwargs):
Window.bind(鼠标位置=self.on鼠标位置)
超级(MyMouse,self)。\uuuuu初始化(**kwargs)
def on_触控向下(自身,*触控):
返回
鼠标位置上的def(自身,*参数):
x、 y=args[1]
self.pos=[x,y-self.mouse\u im\u size[1]]
类别MyApp(应用程序):
def生成(自):
self.root=Builder.load\u串(KV)
MyApp().run()
问题是,当我将鼠标移到应用程序的左边缘或上边缘之外时,光标图像仍保留在应用程序中,我希望鼠标图像消失,就像我将鼠标移到右边缘或下边缘之外一样

问题似乎是鼠标上的
仅在鼠标位于窗口内时才起作用


我想知道鼠标在窗口外时的位置,但我不知道如何在我的任务中使用它。也许有更好的方法可以做到这一点。

您可以通过在光标上使用
窗口
事件
进入
离开
并使用
不透明度属性使光标可见/不可见:

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()
从kivy.app导入应用
从kivy.lang导入生成器
从kivy.uix.button导入按钮
从kivy.uix.textinput导入textinput
从kivy.uix.scatter导入scatter
从kivy.core.window导入窗口
#Window.show\u cursor=False
KV=”“”
浮动布局
盒子布局
MyTextInput
老鼠
身份证号码:themouse
:
字体大小:40
文本:“一些文本”
:
鼠标大小:鼠标大小
自动\u将\u带到\u前端:真
do_旋转:错误
do_比例:错误
是否翻译:错误
形象
id:mouse\u im
尺寸:100,100/self.image\u比率
来源:'光标粉红色.png'
"""
类MyTextInput(TextInput):
通过
类MyMouse(分散):
定义初始(自我,**kwargs):
Window.bind(鼠标位置=self.on鼠标位置)
Window.bind(在光标离开时=self.on光标离开时)
绑定(在光标上输入=self.on光标上输入)
超级(MyMouse,self)。\uuuuu初始化(**kwargs)
def on_触控向下(自身,*触控):
返回
鼠标位置上的def(自身,*参数):
x、 y=args[1]
self.pos=[x,y-self.mouse\u im\u size[1]]
在光标离开时的定义(self,*args):
App.get_running_App().root.ids.themouse.opacity=0
光标上的定义输入(self,*args):
App.get_running_App().root.ids.themouse.opacity=1
类别MyApp(应用程序):
def生成(自):
self.root=Builder.load\u串(KV)
MyApp().run()

我将
mouse
id添加到
MyMouse
小部件中以实现此目的。

这里是另一种方法,但它需要在基本布局周围添加边框:

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()
从kivy.app导入应用
从kivy.clock导入时钟
从kivy.lang导入生成器
从kivy.uix.button导入按钮
从kivy.uix.textinput导入textinput
从kivy.uix.scatter导入scatter
从kivy.core.window导入窗口
#Window.show\u cursor=False
KV=”“”
浮动布局
在以下情况之前:
颜色:
rgba:(1,0,0,1)
矩形:
大小:self.size
pos:self.pos
浮动布局
id:主布局
大小提示:(无,无)
#位置:(50,50)
#位置提示:{'center_x':0.5,'center_y':0.5}
在以下情况之前:
颜色:
rgba:(0,1,0,1)
矩形:
大小:self.size
pos:self.pos
盒子布局
大小提示:(1.0,0.2)
位置提示:{'center_x':0.5,'top':1.0}
MyTextInput
模具视图:
大小提示:(1.0,1.0)
位置提示:{'x':0,'y':0}
老鼠
身份证号码:themouse
:
字体大小:40
文本:“一些文本”
:
鼠标大小:鼠标大小
自动\u将\u带到\u前端:真
do_旋转:错误
do_比例:错误
是否翻译:错误
形象
id:mouse\u im
尺寸:100,100/self.image\u比率
来源:'光标粉红色.png'
"""
类MyTextInput(TextInput):
通过
类MyMouse(分散):
定义初始(自我,**kwargs):
Window.bind(鼠标位置=self.on鼠标位置)
超级(MyMouse,self)。\uuuuu初始化(**kwargs)
def on_触控向下(自身,*触控):
返回
鼠标位置上的def(自身,*参数):
x、 y=args[1]
self.pos=[x,y-self.mouse\u im\u size[1]]
类别MyApp(应用程序):
def生成(自):
self.mainlayout=None
self.mymouse=None
self.root=Builder.load\u串(KV)
Window.bind(size=self.do\u size)
时钟。计划一次(自身大小)
def do_大小(自身,*参数):
如果self.mainlayout为无:
self.mainlayout=self.root.ids.mainlayout
如果self.mymouse为None:
self.mymouse=self.root.ids.themouse
self.mainlayout.size=(self.root.width-2.0*self.mymouse.mouse\u im\u size[0],self.root.height-2.0*self.mymouse.mouse\u im\u size[1])
self.mainlayout.pos=self.mymouse.mouse\u im\u大小
MyApp().run()

这使用了一个
StencilView
将光标的图形剪裁到man布局的内部。

这是一个不错的选择,但理想情况下,我希望完全相同的行为