1

我试图理解不同类型的坐标:

  1. 全球的,
  2. 当地的,
  3. 窗户和
  4. 小部件

坐标。

使用程序: 类 TargetUI(BoxLayout):

js_type = NumericProperty(0)

def __init__(self, **arg):
    super(TargetUI, self).__init__(**arg)
    btn1 = Button(text='Hello world ' + str(self.js_type))
    self.add_widget(btn1)


def on_touch_up(self, touch):
    # here, you don't check if the touch collides or things like that.
    # you just need to check if it's a grabbed touch event
    Logger.info("in touch up")
    Logger.info("global coordinates: " + str(touch.pos))

    if self.collide_point(*touch.pos):

        touch.push()
        # if the touch collides with our widget, let's grab it
        touch.grab(self)
        Logger.info("In widget " + str(self.js_type))

        touch.apply_transform_2d(self.to_local)
        Logger.info("Local coordinates " + str(touch.pos))
        touch.apply_transform_2d(self.to_window)
        Logger.info("Windows coordinates " + str(touch.pos))
        touch.apply_transform_2d(self.to_widget)
        Logger.info("Widget coordinates " + str(touch.pos))
        touch.ungrab(self)

        # and accept the touch.
        return True


class CombWidget(Widget):
     pass

class MyPaintApp(App):   
    def build(self):
        return CombWidget()

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

#:kivy 1.7.1

<CombWidget>:
tg1: tg1
tg2: tg2
tg3: tg3

    BoxLayout:
       size: root.size
       orientation: 'vertical'
       padding: 20

    TargetUI:
                    js_type: 1
        id: tg1


    TargetUI:
                    js_type: 2
        id: tg2


    TargetUI:
                    id: tg3
        js_type: 3

on_touch_up 写出的所有坐标都是相同的,但预计会有一些差异。为什么所有坐标都一样?

我还希望看到 Button 文本以 1,2 或 3 结尾,但它们都是 1。如何使 Button 文本依赖于 self.js_type?

4

2 回答 2

1

这些在坐标发生变化时很有用。例如,对于 scatter 小部件,这是一个示例,其中一个小部件放在 Scatter 中并且您可以移动它(当您再次单击它时它会以某种方式回到原位,但这很方便)。当您这样做时,您应该看到坐标不再相同。理解它们之间的区别留给读者作为练习:)

from kivy.base import runTouchApp
from kivy.lang import Builder

kv = '''
GridLayout:
    cols: 2
    spacing: 10
    ClickBox

    Scatter:
        ClickBox:
            pos: 0, 0
            size: self.parent.size

    Widget:
        ClickBox:
            pos: self.parent.pos
            size: self.parent.size

<ClickBox@Widget>:
    canvas:
        Rectangle:
            pos: self.pos
            size: self.size
    on_touch_move:
        if self.collide_point(*args[1].pos): print self.to_window(*args[1].pos)
        if self.collide_point(*args[1].pos): print self.to_parent(*args[1].pos)
        if self.collide_point(*args[1].pos): print self.to_widget(*args[1].pos)
        if self.collide_point(*args[1].pos): print self.to_local(*args[1].pos)
'''

if __name__ == '__main__':
    runTouchApp(Builder.load_string(kv))
于 2013-09-11T22:23:12.620 回答
1

RelativeLayout的文档为我澄清了这个问题。

父坐标

其他 RelativeLayout 类型的小部件是 Scatter、ScatterLayout 和 ScrollView。如果这样一个特殊的小部件在父堆栈中,只有这样父坐标系和本地坐标系才会偏离窗口坐标系。对于堆栈中的每个这样的小部件,都会创建一个坐标系,该坐标系的 (0, 0) 位于该小部件的左下角。小部件接收和读取的位置和触摸坐标位于其父堆栈(不包括其自身)中最近的特殊小部件的坐标系中,如果没有,则位于窗口坐标中。我们称这些坐标为父坐标。

因此,您必须使用上述特殊小部件之一来获取局部坐标以偏离窗口坐标。Tshirtman 的答案很有效,因为他使用了 scatter 小部件,它是特殊小部件之一。

于 2017-05-24T18:10:05.897 回答