在kivyforpython上运行的这个代码片段绘制了一些矩形(框)作为父窗口小部件(RootWidget)的子窗口小部件。你知道吗
按ALT+D可以创建另一个框(添加到RootWidget)。你知道吗
我正在尝试在父窗口小部件上实现一种触摸和拖动行为,以便在用鼠标拖动所有子框时将它们移动到一起。你知道吗
但是,on\ U touch\ U down方法(请参阅自碰撞点(*触摸.pos))只获取原始子小部件(默认情况下创建的小部件)的位置,而不获取新创建的小部件的位置。你知道吗
为什么?有没有办法更新父对象的大小,以便在触摸第一个框以外的框时将其抓取?你知道吗
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Ellipse, Color, Rectangle, Line
from kivy.core.window import Window
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.properties import NumericProperty, ListProperty
from random import randint
Builder.load_string('''
<Box>:
canvas:
Color:
rgba: .1, .1, 1, .9
Line:
width: 2.
rectangle: (self.x, self.y, self.width, self.height)
''')
class Tree(Widget):
pass
class Node(Widget):
pass
class Box(Widget):
def __init__(self, **kwargs):
super(Box, self).__init__(**kwargs)
self.size = [500, 300]
self.height = self.size[1]
self.width = self.size[0]
self.pos = [500,200]
# bind change of pos to redraw
self.bind(pos=self.redraw, size=self.redraw)
def redraw(self, *args):
# compute head and sisters' positions
self.x = self.pos[0]
self.y = self.pos[1]
#self.height = self.size[0]
#self.width = self.size[1]
class Branches(Widget):
pass
class Terbranch(Widget):
pass
class RootWidget(Widget):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
for i in range(2):
self.add_widget(Box())
self._keyboard = Window.request_keyboard(
self._keyboard_closed, self, 'text')
if self._keyboard.widget:
# If it exists, this widget is a VKeyboard object which you can use
# to change the keyboard layout.
pass
self._keyboard.bind(on_key_down=self._on_keyboard_down)
self.bind(pos=self.redraw, size=self.redraw)
def redraw (self, *args):
pass
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
# if the touch collides with our widget, let's grab it
touch.grab(self)
#print ('touched')
# and accept the touch.
return True
return super(RootWidget, self).on_touch_down(touch)
def on_touch_up(self, touch):
# check if it's a grabbed touch event
if touch.grab_current is self:
# don't forget to ungrab ourself, or you might have side effects
touch.ungrab(self)
# and accept the last up
return True
return super(RootWidget, self).on_touch_up(touch)
def on_touch_move(self, touch):
# check if it's a grabbed touch event
if touch.grab_current is self:
#self.pos = touch.pos
self.pos[0] += touch.dx
self.pos[1] += touch.dy
#redraw moved children
for child in self.children:
child.pos[0] += touch.dx
child.pos[1] += touch.dy
child.redraw()
# and accept the last move
return True
return super(RootWidget, self).on_touch_move(touch)
def _keyboard_closed(self):
print('My keyboard have been closed!')
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
self._keyboard = None
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
#print('The key', keycode, 'have been pressed')
#print(' - text is %r' % text)
#print(' - modifiers are %r' % modifiers)
# Keycode is composed of an integer + a string
# If we hit escape, release the keyboard
if keycode[1] == 'escape':
keyboard.release()
elif keycode[1] == 'd' and modifiers[0] == 'alt':
newbox = Box()
self.add_widget(newbox)
# Return True to accept the key. Otherwise, it will be used by
# the system.
return True
def update(self, dt):
pass
class MyApp(App):
def build(self):
rw = RootWidget()
#Clock.schedule_interval(rw.update, 0.2)
return rw
if __name__ == "__main__":
MyApp().run()
我不确定我是否完全理解您的问题,但是在您的
on_touch_move
方法中,您正在移动所有子Box
实例。但是你也在改变RootWidget
本身的pos
。由于RootWidget
是App
的根窗口,因此更改其pos
属性不会产生任何视觉效果。但是,该更改会影响self.collide_point
方法(它使用pos
和size
检查冲突)。所以,如果我理解你的问题,你只需要省去改变RootWidget
的pos
:相关问题 更多 >
编程相关推荐