Kivy小部件在ScrollView中的定位

0 投票
1 回答
1061 浏览
提问于 2025-04-18 10:01

我在一个滚动视图里的网格布局中有一个标签。我的目标是通过代码在这个标签上画一条斜线(还有其他一些事情)。我尝试用以下代码来实现这个目标:

with l.canvas: #l is my label
    Color(1.0, 0.0, 0.0)
    Line(points=[l.x, l.y, l.x+l.width, l.y+.height], width=1.2, cap='square')

但是,这段代码画出了一条红线,起点在屏幕的左下角,也就是位置(0, 0),根本没有靠近我的标签。如果让我猜测问题出在哪里,我觉得可能是因为这个位置是相对于滚动视图的,而我想要的是相对于网格布局的。我试过使用 l.to_locall.to_parentl.to_widgetl.to_window,但它们都返回(0, 0)。我该如何获取标签的正确位置,以便这条线能画在标签内部呢?

1 个回答

1

你没有说明这段代码是写在哪里的,但我猜是在小部件的 __init__ 方法里。

假设是这样的话,这是因为小部件的位置一开始是 0, 0,直到它的父级设置它的位置(比如说,一个 BoxLayout 会把它的孩子们排成一行),这个过程发生在 __init__ 之后。也就是说,画线的时候线是画在正确的位置,但标签后来被移动了,而线的位置没有变,因为你没有告诉它去做其他事情。

你可以通过保留对这条线的引用,并在其他东西变化时重置它的点来解决这个问题。

with l.canvas: #l is my label
    Color(1.0, 0.0, 0.0)
    l.line = Line(points=[l.x, l.y, l.x+l.width, l.y+.height], width=1.2, cap='square')
l.bind(pos=line_reset_func, size=line_reset_func)

...在这里你显然需要定义一个叫 line_reset_func 的函数,它需要两个参数(我想是标签实例和新的位置或大小值),然后改变 instance.line 的点。如果你定义了自己的标签子类,这个函数最自然的地方就是作为 l 的一个方法。

而使用 kv 的话,这些事情会自动处理,这样可以让事情变得简单一些,这也是我们推荐尽可能使用它的原因之一。

撰写回答