Kivy 中的动态小部件画布大小调整

问题描述 投票:0回答:1

当我将 Widget 对象添加到 .kv 文件中的 BoxLayout 时,它会按照我的预期操作并填充屏幕顶部的可用空间。但是,当我在 Python 中动态添加 Widget 时,它不会出现在屏幕顶部,也不会像我预期的那样占用屏幕的全部剩余空间。

我创建了一个小示例程序来演示我的问题。

当我将 Widget 对象添加到 .kv 文件中的 BoxLayout 时,它会按照我的预期操作并填充屏幕顶部的可用空间。这是 kv 文件和结果屏幕:

KV 文件

BoxLayout:
    orientation: 'vertical'
    Widget:
        canvas:
            Color:
                rgb: 1, 0, 0
            Rectangle:
                size: self.size
                pos:  self.pos
    Button:
        size_hint: .5, None
        pos_hint: {'center_x': .5}
        height: 100
        text: 'My Button'

结果:

Expected Results

当我从 kv 文件中取出 Widget 并尝试在单击按钮时将其动态添加到 BoxLayout 中时,它不会出现在屏幕顶部,也不会按预期占用全部剩余空间。

新的 KV 文件(test.kv):

BoxLayout:
    orientation: 'vertical'
    Button:
        size_hint: .5, None
        pos_hint: {'center_x': .5}
        height: 100
        text: 'My Button'
        on_release: app.on_btn_release()

Python:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.graphics import Color, Rectangle


class TestApp(App):

    def build(self):
        self.root = Builder.load_file('test.kv')
        return self.root
    
    def on_btn_release(self):
        wid = Widget()
        wid.size_hint = (1,1)
        with wid.canvas:
            Color(rgb=(1,0,0))
            Rectangle(size=wid.size, pos=wid.pos)
        self.root.add_widget(wid, 1)    

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

结果:

Bad Results

我尝试将画布指令移至 add_widget() 调用之后,但这没有帮助。我知道问题在于,在将指令添加到画布时,尚未调整小部件的大小以填充框布局。我知道这一点,因为如果我添加第二个按钮来添加画布指令,并在单击第一个按钮后单击该按钮,则它可以正常工作。我只是想知道如何在单击第一个按钮时执行此操作。

python kivy widget
1个回答
0
投票

正如你所说,问题是在执行

canvas
指令时,小部件的大小和位置是其初始默认值。在 python 中定义画布指令不会设置任何绑定,以便在小部件大小和/或位置发生变化时对这些
canvas
指令进行调整。解决此问题的一种方法是设置这些绑定,如下所示:

def on_btn_release(self):
    wid = Widget()
    wid.size_hint = (1, 1)
    with wid.canvas:
        Color(rgb=(1, 0, 0))
        Rectangle(size=wid.size, pos=wid.pos)
    wid.bind(size=self.wid_changed)
    wid.bind(pos=self.wid_changed)
    self.root.add_widget(wid, 1)

def wid_changed(self, wid, new_attr):
    wid.canvas.clear()
    with wid.canvas:
        Color(rgb=(1, 0, 0))
        Rectangle(size=wid.size, pos=wid.pos)

您还可以使用

kv
中定义
canvas
指令的规则定义自定义小部件,以便
kv
为您设置绑定。

© www.soinside.com 2019 - 2024. All rights reserved.