Kivy中浮动布局添加自定义大小的控件

1 投票
1 回答
1685 浏览
提问于 2025-04-18 12:59

我刚开始学习Python和Kivy,想通过制作一个小部件来学习:

这是我的Main.py文件:

class start(App):
    def build(self):
        return Holder()

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

代码如下:

class Holder(FloatLayout):
    def __init__(self, **kwargs):
        self.size=(300,300)
        super(Holder,self).__init__(**kwargs)

        c=Cell()
        c.pos=(100,100)
        self.add_widget(c)
        print(str(c.pos))

        d=Cell()
        d.pos=(100,0)
        self.add_widget(d)
        print(str(d.pos))

class Cell(Widget):
    def __init__(self, **kwargs):
        super(Cell,self).__init__(**kwargs)
        with self.canvas:
            Color(1, 0, 0)
            Rectangle(size=(50, 50))

        self.height=50
        self.width=50

我遇到的问题是,虽然我添加了两个位置不同的单元格,但它们还是重叠在一起,并且都只显示在角落里。

在这里输入图片描述

你能帮我看看我哪里出错了吗?

编辑:
我更新了单元格的代码,如下所示:

class Cell(Widget):
    rect=Rectangle(size=(50, 50))
    def __init__(self, **kwargs):
        super(Cell,self).__init__(**kwargs)
        self.canvas.add(Color(1, 0, 0))
        self.canvas.add(self.rect)
        self.bind(pos=self.callback_pos)

    def callback_pos(self, value):
        self.rect.pos=self.pos

不过,现在我收到的错误是“TypeError: callback_pos()接受2个位置参数,但给了3个”。

1 个回答

1

你的绘图代码是

with self.canvas:
            Color(1, 0, 0)
            Rectangle(size=(50, 50))

...这就是你看到的效果,两个矩形的大小都是(50, 50),位置在默认的(0, 0),因为你没有设置位置。

如果你想让矩形的大小和形状跟你的控件一致,你需要自己绑定这个矩形。也就是说,要保存一个矩形的引用,并使用控件的bind方法,调用一个函数来更新矩形的位置,每当控件的位置变化时。

这样说可能有点啰嗦,所以我们推荐使用kv语言——它可以为你自动处理这些事情!

<Cell>:
    canvas:
        Color:
            rgb: 1, 0, 0
        Rectangle:
            pos: self.pos
            size: 50, 50

这样一来,每当位置变化时,矩形的位置会自动更新为和控件的位置一致。

你做过kivy的乒乓球教程吗?我推荐你去试试。你可能还会对我的视频教程感兴趣。

编辑:回复你自己的编辑:

rect=Rectangle(size=(50, 50))

你应该把这行代码放在__init__里,你现在的写法会把同一个矩形传给每一个实例,因为这是一个类级别的变量。这样做可能不会崩溃并且在这里能工作,但这并不是你想要的,可能也不是个好习惯。

不过,现在我收到的错误是“TypeError: callback_pos() takes 2 positional arguments but 3 were given”

你有两个参数self, value。绑定(以及所有kivy属性绑定)实际上是用self, instance, value来调用的。只需添加这个额外的参数(或者用*args来捕获所有参数)。

撰写回答