You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kivy中collide_point()无法识别鼠标悬停问题求助

Kivy鼠标悬停控件位置偏移问题解决

问题根源

Window.mouse_pos返回的是窗口全局坐标系的坐标(原点在窗口左下角),而Widget.collide_point()方法接收的是当前控件父容器坐标系的坐标,直接传递窗口坐标会导致坐标系不匹配,出现识别位置偏移的问题。

解决方法

需要将窗口全局坐标转换为当前控件的本地坐标(或父容器坐标)后再进行碰撞检测。最简单的方式是使用to_widget()方法完成坐标转换,再传入collide_point()。

修改HoverButton类中的check_for_hover方法:

def check_for_hover(self, *args):
    mouse_pos = args[1]
    # 将窗口坐标转换为控件本地坐标
    local_x, local_y = self.to_widget(*mouse_pos)
    if self.collide_point(local_x, local_y):
        print('cursor inside widget')
        self.text = 'cursor inside'
    else:
        print('cursor outside widget')
        self.text = 'cursor outside'

完整代码

Python代码

from kivy.app import App
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout

class HoverButton(Button):
    def __init__(self, **kwargs):
        super(HoverButton, self).__init__(**kwargs)
        Window.bind(mouse_pos=self.check_for_hover)

    def check_for_hover(self, *args):
        mouse_pos = args[1]
        # 转换窗口坐标为控件本地坐标
        local_x, local_y = self.to_widget(*mouse_pos)
        if self.collide_point(local_x, local_y):
            print('cursor inside widget')
            self.text = 'cursor inside'
        else:
            print('cursor outside widget')
            self.text = 'cursor outside'

class Frame(FloatLayout):
    pass

class HoverApp(App):
    def build(self):
        return Frame()

if __name__ == '__main__':
    HoverApp().run()

KV语言文件

#: kivy 2.2.0
<Frame>
    HoverButton:
        pos_hint: {'x': .4, 'y': .4}
        size_hint: (.2, .2)
        text: 'cursor outside'
        font_size: '22sp'

补充说明

  • to_widget(x, y):将窗口全局坐标转换为当前控件的本地坐标,转换后的值可直接传入collide_point()完成碰撞检测。
  • 若需要基于父容器坐标系检测,可使用self.to_widget(*mouse_pos, relative=True)获取父容器坐标后传入collide_point()。

内容的提问来源于stack exchange,提问作者mishaeel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 03:38:29