簡體   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