Kivy Place Scatter 在 FloatLayout 的中心

Kivy Place Scatter in the center of FloatLayout

您好,我正在关注 Kivy 上的 Crash Course Youtube 教程。 https://www.youtube.com/watch?v=2Gc8iYJQ_qk&t=495s

在视频 #8 中,教程使用 kv 语言将散点放置在 FloatLayout 的中心,但存在一个问题,因为每次我们调整 window 的大小时,散点都会回到中心。

我想将散点放在中心,并且在调整 window 大小时不移动。视频建议我们在 python 代码中创建 属性,这样我们就没有自动绑定。到目前为止,这是我的代码:

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.scatter import Scatter
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty, ObjectProperty
from kivy.graphics import (Rectangle,
                           Ellipse,
                           Line,
                           Color)

import random

class ScatterTextWidget(BoxLayout):

    text_color = ListProperty([1, 0, 0, 1])
    scatter = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(ScatterTextWidget, self).__init__(**kwargs)
        self.scatter.center = self.scatter.parent.center

    def change_label_color(self, *args):
        color = [random.random() for i in range(3)] + [1]
        self.text_color = color

class TutorialApp(App):
    def build(self):
        return ScatterTextWidget()

这是 kv 文件:

#:kivy 1.10

<ScatterTextWidget>:
    scatter: scatter_id
    orientation: 'vertical'
    TextInput:
        id: my_textinput
        font_size: 150
        size_hint_y: None
        height: 200
        text: "default"
        on_text: root.change_label_color()

    FloatLayout:
        id: float_layout
        canvas:
            Color:
                rgba: 0, 0, 1, 0.5
            Rectangle:
                pos: self.pos
                size: self.size
        Scatter:
            id: scatter_id
            size_hint: None, None
            size: my_label.size
            #center: self.parent.center
            canvas.after:
                Color:
                    rgba: 1, 0, 0, 0.5
                Rectangle:
                    size: self.size
                    pos: self.pos
            Label:
                id: my_label
                text: my_textinput.text
                font_size: 150
                size: self.texture_size
                color: root.text_color
                canvas:
                    Color:
                        rgba: 0, 1, 0, 0.5
                    Rectangle:
                        pos: self.pos
                        size: self.size

    BoxLayout:
        orientation: 'horizontal'
        size_hint_y: None
        height: 150
        canvas:
            Color:
                rgba: 1, 0, 0, 0.5
            Rectangle:
                pos: self.pos
                size: self.size
        Label:
            id: label1
            text: my_textinput.text[:3][::-1]
            font_size: 100
            color: root.text_color
        Label:
            id: label2
            text: my_textinput.text[-3:][::-1]
            font_size: 100
            color: root.text_color

使用此代码,散点图不会放置在散点图的中心,我不知道为什么以及如何修复它。

Scatter 没有居中,因为行:

self.scatter.center = self.scatter.parent.center

执行的太早了,当FloatLayout的大小还是默认的(100,100)时,它的默认位置是(0,0),而center还是默认值为 (50,50)。要获得正确的居中,您必须延迟该行的执行,直到根据 kv 文件规则设置 sizeposcenter。为此,您可以使用 Clock.schedule_once(),如下所示:

class ScatterTextWidget(BoxLayout):

    text_color = ListProperty([1, 0, 0, 1])
    scatter = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(ScatterTextWidget, self).__init__(**kwargs)
        Clock.schedule_once(self.center_it)
        # self.scatter.center = self.scatter.parent.center

    def change_label_color(self, *args):
        color = [random.random() for i in range(3)] + [1]
        self.text_color = color

    def center_it(self, dt):
        self.scatter.center = self.scatter.parent.center