【问题标题】:How to assign a canvas to multiple widgets in Kivy如何将画布分配给 Kivy 中的多个小部件
【发布时间】:2019-01-21 21:40:52
【问题描述】:

我想给屏幕上的所有小部件一个白色画布。我知道如何在KV 中创建预期的画布,但在这种情况下,我必须使用 Python 代码。

在我的代码中,我尝试了self.cavas.add(...),在下面的代码中,我使用了with self.canvas:。两次尝试都导致画布被绘制在屏幕一角,而不是小部件内部。

如何使用 Python 代码将画布放在每个小部件的内部?

代码

from kivy.app import App
from kivy.core.window import Window
from kivy.graphics.context_instructions import Color
from kivy.graphics.vertex_instructions import Rectangle
from kivy.lang import Builder
from random import random
from kivy.uix.button import Button
from kivy.animation import Animation
from kivy.clock import Clock

class LittleButtons(Button):

    dur = 2

    def reup(self, *args):

        Animation.cancel_all(self)
        Animation(pos_hint = {'center_x': random(), 'center_y': random()}, duration = self.dur).start(self)

    def __init__(self, **kwargs):

        super(LittleButtons, self).__init__(**kwargs)
        self.pos_hint = {'center_x': random(), 'center_y': random()}
        self.size_hint = None, None
        self.width = random() * (Window.width / 20)
        self.height = self.width
        self.background_color = [0,0,0,.05]
        with self.canvas:
            Color(rgba = [1,1,1,.2])
            Rectangle(pos = self.pos, size = self.size)

        Animation(pos_hint = {'center_x': random(), 'center_y': random()}, duration = self.dur).start(self)
        Clock.schedule_interval(self.reup, self.dur)

KV = Builder.load_string("""
#:import Factory kivy.factory.Factory

Screen:
    FloatLayout:
        on_parent:
            (lambda ltext: [self.add_widget(Factory.LittleButtons(text=ltext)) for i in range (150)])('hi!')
        Button:
            background_color: 0,0,0,0
            canvas:
                Color:
                    rgba: 0,1,1,1
                Rectangle:
                    pos: self.pos
                    size:self.size
""")

class MyApp(App):
    def build(self):
        return KV

if __name__ == '__main__':
    MyApp().run()

【问题讨论】:

    标签: python canvas kivy


    【解决方案1】:

    问题是在LittleButtons__init__()方法中,它的位置还是默认的(0,0),所以Rectangle的位置设置为(0,0)。当您使用KV 时,它巧妙地将Rectangle 位置绑定到您引用self.pos 时的LittleButtons 位置。不幸的是,在.py 文件中,您必须自己提供该绑定。因此,这是对您的 LittleButtons 的修改,它应该可以处理位置变化:

    class LittleButtons(Button):
    
        dur = 2
    
        def reup(self, *args):
    
            Animation.cancel_all(self)
            Animation(pos_hint = {'center_x': random(), 'center_y': random()}, duration = self.dur).start(self)
    
        def __init__(self, **kwargs):
            self.rect = None
            super(LittleButtons, self).__init__(**kwargs)
            self.pos_hint = {'center_x': random(), 'center_y': random()}
            self.size_hint = None, None
            self.width = random() * (Window.width / 20)
            self.height = self.width
            self.background_color = [0,0,0,.05]
            with self.canvas:
                Color(rgba = [1,1,1,.2])
                self.rect = Rectangle(pos = self.pos, size = self.size)
    
            Animation(pos_hint = {'center_x': random(), 'center_y': random()}, duration = self.dur).start(self)
            Clock.schedule_interval(self.reup, self.dur)
    
    
        def on_pos(self, instance, pos):
            if self.rect is not None:
                self.rect.pos = pos
    

    更改是添加了self.rect 属性和on_pos 方法。

    如果您需要处理 size 的变化,您可以添加类似的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-11
      • 2018-09-20
      • 1970-01-01
      • 2014-06-30
      • 1970-01-01
      相关资源
      最近更新 更多