如何使用 Python 为 Kivy BoxLayout 设置背景?

How do I give a Kivy BoxLayout a Background using Python?

也对其他非按钮小部件感兴趣,例如 GridLayout 或 Label。大多数情况下,我对 BorderImages 感兴趣,但当然欢迎讨论常规图像的答案。

我发现了很多使用 Builder 和 KV 文件的示例,但我有兴趣纯粹在 Python 中进行操作。这是我现在正在尝试的:

    ab = BoxLayout(orientation='horizontal',
                   height=self.widgetHeight,
                   size_hint_y=None)
    with ab.canvas.before:
        BorderImage(
            width=self.width,
            height=self.widgetHeight,
            pos=(0,0),
            border=(15, 15, 15, 15),
            source='button-up.png')

这不起作用,但也不会报错。

编辑:收到 Inclement 和 Totem 的评论后,非常感谢您提供这些文件,但恐怕我已经看过这些文件了。当我遵循这些文档时,我将分享更多关于我正在做的事情的细节:

def redrawAB(self,*args,**kwargs):
    self.bg_rect.size = self.size
    self.bg_rect.pos = self.pos
def myActionBar(self):
    ab = BoxLayout(orientation='horizontal', 
        height=self.widgetHeight,
        size_hint_y=None)
    with ab.canvas:
        ab.bg_rect = BorderImage(width=self.width,
            height=self.widgetHeight,
            pos=(0,0), border=(15, 15, 15, 15),
            source='button.png')
    ab.bind(pos=self.redrawAB, size=self.redrawAB)
    return ab

虽然我认为这不是相关的细节,但在代码的其他地方,我们这样做:

 widget.add_widget(self.myActionBar())

根据以上内容,应用程序将在启动时崩溃并出现以下错误:

  AttributeError: 'InterfaceManager' object has no attribute 'bg_rect'

"InterfaceManager" 是这些东西的父控件。所以我想不知何故我需要让 redrawAB() 知道 ab.bg_rect 对象,我不确定如何让 ab.bind() 传递对对象的引用?

这是另一个失败的尝试。我没有收到任何错误,但是我没有收到带有界面小部件的可用对象(我只是在屏幕上应该去的地方有一个空白区域):

class MyActionBar(BoxLayout):
    def __init__(self, **kwargs):
        super(BoxLayout, self).__init__(**kwargs)

        self.height=kwargs['height']
        self.orientation='horizontal'
        self.size_hint_y=None

        with self.canvas:
            self.bg_rect = BorderImage(border=(15, 15, 15, 15), source='button.png')
        self.bind(pos=self.redrawAB, size=self.redrawAB)

    def redrawAB(self,*args,**kwargs):
        self.bg_rect.size = self.size
        self.bg_rect.pos = self.pos

#...in another class comes the following...

    parent_boxlayout.add_widget(MyActionBar(height=128))

我正在回答我自己的问题,因为我找到了解决方法。

首先是先创建一个带背景图片的AnchorLayout,然后依次创建BoxLayout,像这样:

a = AnchorLayout(anchor_x='center', anchor_y='center')
i = Image(source='thing.png')
a.add_widget(i)
b = BoxLayout(orientation='horizontal')
a.add_widget(b)

更传统、更痛苦的方法:不要将背景放在 BoxLayout 上(目标是将其他小部件放在它前面),只需将图像分成块并将每个块放入 BoxLayout在按钮(或图像,如果你不需要按钮行为)中,像这样:

    ab = BoxLayout(orientation='horizontal', height=self.widgetHeight, size_hint_y=None)
    bt = Button(background_normal='left.png', size_hint_x=None, width=self.widgetHeight)
    ab.add_widget(bt)
    bt = Button(background_normal='right.png',text='Second',border=(10,10,10,10))
    ab.add_widget(bt)