我创建了一个可点击的图片,我可以旋转它,但我无法获得正确的旋转原点。以下代码将两个图像(其中一个可单击)放置到表单上。我希望它们在彼此之上,可点击的一个旋转。可点击的一个旋转,但旋转原点是图像中心以外的其他东西导致它被移动,即使我指定中心是我期望的。有趣的是,它是可点击的,但点击区域应该是:在不可点击的图像上。也就是说,单击蓝色图像时红色图像变为绿色!
我从网上找到的一些kv语言修改了这段代码,并且轮换工作正常。但我需要以编程方式设置按钮,因为我最终会有一个包含许多的表单,每个表单都会以不同的方式旋转和移动。
我觉得问题在于坐标单位不匹配,但我在网上和文档中找不到多少。任何帮助表示赞赏。图像只有32x32图标,您可以用任何方便的图标替换它们。
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.graphics.context_instructions import PopMatrix, PushMatrix
from kivy.graphics import Rotate
from kivy.uix.behaviors import ButtonBehavior
h = .05
w = h * 1.6
class IconButton(ButtonBehavior, Image):
def __init__(self, angle=0, **kwargs):
super(IconButton, self).__init__(**kwargs)
self.canvas.before.add(PushMatrix())
self.canvas.before.add(Rotate(angle = angle, origin = [self.get_center_x(), self.get_center_y()]))
self.canvas.after.add(PopMatrix())
def on_press(event):
event.source = event.img_dn
print '{} pressed'.format(event.id)
def on_release(event):
event.source = event.img_up
print '{} released'.format(event.id)
class TestApp(App):
def build(self):
layout = FloatLayout()
btn = IconButton(angle=-20, id='b1', size_hint=(h,w), pos_hint = {'center_x': .25, 'center_y': .9})
btn.img_up = 'loudspeaker_red_32.png'
btn.img_dn = 'loudspeaker_green_32.png'
btn.source = btn.img_up
layout.add_widget(btn)
im = Image(id='i1', size_hint=(h,w), pos_hint = {'center_x': .25, 'center_y': .9})
im.source = 'loudspeaker_blue_32.png'
layout.add_widget(im)
return layout
class MainApp(App):
def build(self):
layout = Builder.load_string(src)
return layout
if __name__ == '__main__':
TestApp().run()
答案 0 :(得分:2)
如果您尝试在窗口小部件周围绘制一条线(一种非常有用的调试技术),您会发现在IconButton.__init__()
被调用时pos
属性仍然是(0, 0)
并且代码认为您的按钮位于左下角。
class IconButton(ButtonBehavior, Image):
def __init__(self, angle=0, **kwargs):
super(IconButton, self).__init__(**kwargs)
self.canvas.before.add(PushMatrix())
self.canvas.add(Color(rgba=(1,0,0,.5)))
self.canvas.add(Line(rectangle=(self.x, self.y, self.width, self.height)))
self.canvas.after.add(PopMatrix())
def on_press(event):
event.source = event.img_dn
print '{} pressed'.format(event.id)
def on_release(event):
event.source = event.img_up
print '{} released'.format(event.id)
当您的窗口小部件放置在布局中时,会发生这种情况。pos
属性已实现。当您创建Widget时,它不知道它将被放置在何处。这就是为什么你需要在以后调用的on_pos
方法中实现旋转原点,当所有属性设置正确时:
class IconButton(ButtonBehavior, Image):
def __init__(self, angle=0, **kwargs):
super(IconButton, self).__init__(**kwargs)
self.rotate = Rotate(angle = angle)
self.canvas.before.add(PushMatrix())
self.canvas.before.add(self.rotate)
self.canvas.after.add(PopMatrix())
self.bind(pos=self.update_canvas)
self.bind(size=self.update_canvas)
def update_canvas(self, *args):
self.rotate.origin = self.center
def on_press(event):
event.source = event.img_dn
print '{} pressed'.format(event.id)
def on_release(event):
event.source = event.img_up
print '{} released'.format(event.id)
这种不便使我们更倾向于使用.kv语言来描述布局。