已禁用 collide_point RelativeLayout 与 StencilView
KIVY collide_point RelativeLayout vs StencilView
我从 Python 中的 Kivy – Interactive Applications and Games - Second Edition by Roberto Ulloa 开始学习 KIVY”。
我试图通过示例程序来理解 collide_point。
在具有以下示例代码的 RelativeLayout 中,我能够识别何时在水平线上单击了鼠标。但是,如果我使用 StencilView,我将无法捕获触摸事件。
请帮忙
from kivy.app import App
from kivy.graphics import Line
from kivy.uix.scatter import Scatter
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.stencilview import StencilView
class MyPaintWidget(Scatter):
def __init__(self, **kwargs) :
self.selected = None
self.touched = False
super(MyPaintWidget, self).__init__(**kwargs)
def create_figure(self, **kwargs):
(ix,iy) = self.to_local(*self.pos)
(fx,fy) = self.to_local(self.pos[0] + self.size[0], self.pos[1] + self.size[1])
print ("ix " + str(ix) + " iy " + str(iy) + " fx " + str(fx) + " fy " + str(fy))
self.canvas.add(Line( points=[ix, iy, fx, fy], width=1))
return self
def on_touch_down(self, touch):
if self.collide_point(touch.x, touch.y):
#This print I get for RelativeLayout
#But for StencilView it does not work when I touch the line
print("Hi you touched the line")
class MyPaintApp(App):
def build(self):
#If parent is StencilView unable to click
#but if parent is RelativeLayout, I am able to get collide_point
#parent = StencilView()
parent = RelativeLayout()
#parent = Scatter()
ix = 100.
iy = 100.
fx = 200.
fy = 100.
pos = (min(ix, fx), min(iy, fy))
size = (abs(fx-ix), abs(fy-iy))
self.painter = MyPaintWidget(pos=pos, size=size)
parent.add_widget(self.painter.create_figure())
return parent
if __name__ == '__main__':
MyPaintApp().run()
StencilView
的 documentation 说:
Note
StencilView is not a layout. Consequently, you have to manage the size
and position of its children directly. You can combine (subclass both)
a StencilView and a Layout in order to achieve a layout’s behavior.
因此,您为其子项设置的 size
将被使用,而 size_hint
将被忽略。根据您的计算,您的 MyPaintWidget
的 size
为 (100.0, 0.0)
。 0 的高度永远不会 return True
值 collide_point()
。
但是,当您使用 RelativeLayout
时,size_hint
不会被忽略,并且由于 size_hint
的默认值是 (1,1)
,您的 MyPaintWidget
结束使用与您的 App
相同的尺码。您计算的 size
将被忽略,您的大部分 collide_point()
调用都会得到 True
结果。
要获得一致的结果,请将 size_hint=(None, None)
添加到您的 MyPaintWidget(pos=pos, size=size)
。当然,height
为 0 时,您将永远不会发生碰撞。
我从 Python 中的 Kivy – Interactive Applications and Games - Second Edition by Roberto Ulloa 开始学习 KIVY”。 我试图通过示例程序来理解 collide_point。
在具有以下示例代码的 RelativeLayout 中,我能够识别何时在水平线上单击了鼠标。但是,如果我使用 StencilView,我将无法捕获触摸事件。
请帮忙
from kivy.app import App
from kivy.graphics import Line
from kivy.uix.scatter import Scatter
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.stencilview import StencilView
class MyPaintWidget(Scatter):
def __init__(self, **kwargs) :
self.selected = None
self.touched = False
super(MyPaintWidget, self).__init__(**kwargs)
def create_figure(self, **kwargs):
(ix,iy) = self.to_local(*self.pos)
(fx,fy) = self.to_local(self.pos[0] + self.size[0], self.pos[1] + self.size[1])
print ("ix " + str(ix) + " iy " + str(iy) + " fx " + str(fx) + " fy " + str(fy))
self.canvas.add(Line( points=[ix, iy, fx, fy], width=1))
return self
def on_touch_down(self, touch):
if self.collide_point(touch.x, touch.y):
#This print I get for RelativeLayout
#But for StencilView it does not work when I touch the line
print("Hi you touched the line")
class MyPaintApp(App):
def build(self):
#If parent is StencilView unable to click
#but if parent is RelativeLayout, I am able to get collide_point
#parent = StencilView()
parent = RelativeLayout()
#parent = Scatter()
ix = 100.
iy = 100.
fx = 200.
fy = 100.
pos = (min(ix, fx), min(iy, fy))
size = (abs(fx-ix), abs(fy-iy))
self.painter = MyPaintWidget(pos=pos, size=size)
parent.add_widget(self.painter.create_figure())
return parent
if __name__ == '__main__':
MyPaintApp().run()
StencilView
的 documentation 说:
Note
StencilView is not a layout. Consequently, you have to manage the size and position of its children directly. You can combine (subclass both) a StencilView and a Layout in order to achieve a layout’s behavior.
因此,您为其子项设置的 size
将被使用,而 size_hint
将被忽略。根据您的计算,您的 MyPaintWidget
的 size
为 (100.0, 0.0)
。 0 的高度永远不会 return True
值 collide_point()
。
但是,当您使用 RelativeLayout
时,size_hint
不会被忽略,并且由于 size_hint
的默认值是 (1,1)
,您的 MyPaintWidget
结束使用与您的 App
相同的尺码。您计算的 size
将被忽略,您的大部分 collide_point()
调用都会得到 True
结果。
要获得一致的结果,请将 size_hint=(None, None)
添加到您的 MyPaintWidget(pos=pos, size=size)
。当然,height
为 0 时,您将永远不会发生碰撞。