繁体   English   中英

Kivy:旋转可点击的图像

[英]Kivy: Rotate clickable image

我已经创建了一个可点击的图像,可以旋转它,但是不能正确获得旋转的原点。 下面的代码将两个图像(其中一个可单击)放置在窗体上。 我希望它们彼此叠置,并旋转可点击的。 可单击的对象被旋转了,但是旋转原点是不同于图像中心的东西,即使它指定了我希望的中心,它也会导致图像中心被移动。 有趣的是,它是可单击的,但单击区域应位于该位置:在不可单击的图像上。 也就是说,单击蓝色图像时,红色图像变为绿色!

我用网上找到的一些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()

如果尝试在小部件周围画一条线(一种非常有用的调试技术),则会发现在IconButton.__init__() pos IconButton.__init__()仍然为(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属性。 当您创建窗口小部件时,它不知道将其放置在何处。 这就是为什么在正确设置所有属性后,需要在稍后调用的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语言来描述布局的确切原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM