Kivy 圆形菜单

1 投票
1 回答
674 浏览
提问于 2025-04-18 07:38

我想用Kivy写一个圆形的菜单。最后的效果应该像这样:

这里输入图片描述

在开始的时候我遇到了一些问题。我已经创建了“主菜单”按钮(0.1)。现在我想再创建两个新的菜单圆圈,分别是2.1和2.2。问题是,当我点击主按钮时,这两个新按钮的事件会被触发,但点击新按钮时却没有任何反应。
我非常感谢任何帮助。:)

menu.py

import kivy
kivy.require('1.8.0') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.label import Label
from kivy.factory import Factory
from kivy.uix.scatter import Scatter
from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout

from kivy.lang import Builder

class menuApp(App):
    print "test"
    def secTouch(self):
        print "sectouch"


class RootWidget(FloatLayout):
pass


class Menu (FloatLayout):
def newMenu(self):
    dynamicMenu = Factory.First()
    self.add_widget(dynamicMenu)
    pass

class First(Scatter):

    def firstTouch(self):
        dynamicWidget = Factory.Second()
        self.add_widget(dynamicWidget)    
    print "touch"
    pass

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

menu.kv

#:kivy 1.8.0
#: set buttonSize 100, 100
#: set middleOfScreen 0,0

RootWidget:
<RootWidget>:
    Menu

<Menu>
    on_touch_down: root.newMenu()

<First>:
    id: first
    pos: root.size[0]/2-self.size[0]/2, root.size[1]/2-self.size[1]/2
    size: 100, 100
size_hint: None, None
Widget:
    on_touch_down: root.firstTouch()
    id: me
    size_hint: None, None
    size: 100, 100
    pos: root.size[0]/2-self.size[0]/2, root.size[1]/2-self.size[1]/2

    canvas:
        Color:
            rgb: 1, 0, 0
        Ellipse:
            pos: me.pos
            size: buttonSize


<Second@Scatter>:
pos: root.size[0]/2-self.size[0]/2+40, root.size[1]/2-self.size[1]/2+40
size: 100, 100
size_hint: None, None
on_touch_down: app.secTouch()
canvas:
    Color:
        rgb: 1, 0, 0
    Ellipse:
        pos: root.size[0]/2-self.size[0]/2+40, root.size[1]/2-self.size[1]/2+40
        size: buttonSize

1 个回答

2

每次触摸事件都会被发送到 on_touch_down 事件处理器,而不仅仅是特定区域内的触摸(比如在某个小部件内)。无论你在屏幕的哪个地方触摸,Menuon_touch_down 都会被触发。你应该使用 collide_point() 来确保触摸是在指定的范围内。

Kivy指南中的 抓取触摸事件 部分有关于 collide_point() 的示例,以及一些关于触摸事件的更多信息。

但是,基本的想法是:

def on_touch_down(self, touch):
    if self.collide_point(*touch.pos):
        # do stuff here
        return True  # 'handle' the event so it will not propagate

撰写回答