画布边框不会更新 ScrollView Kivy 中的位置

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

我想使用 Kivy 创建一个待办事项应用程序。当我使用标签添加任务时,它会显示边框,该边框是使用画布创建的。问题是边框遵循最后创建的元素,因此只有一个任务出现,而其他任务则没有边框。仅当我包含 ScrollView 时才会出现此问题。

**下图问题:**

代码:

class TasksBox(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.size_hint = (1, None)
        self.cols = 1

        self.bind(minimum_height=self.setter("height"))

class ScrollBox(ScrollView):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.size_hint = (1, None)
        self.size = (Window.width, Window.height)

class MainWidget(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.size_hint = (1, None)
        self.cols = 1
        self.spacing = dp(10)
        self.padding = dp(10)
        self.size_hint = (1, 1)
        self.bind(size=lambda instance, value: self.update_size(instance, value, (1, 1, 1)))
        self.btn_height = dp(40)
        self.text_value = ""

        add_button = AddButton(self.btn_height).create()
        self.task_field = TaskField(self.btn_height).create()
        add_button.bind(on_press=self.create_task)
        self.task_field.bind(on_text_validate=self.create_task)

        self.task_field.bind(text=self.get_value)

        # text input + submit button
        box = BoxLayout(size_hint=(1, None), height=self.btn_height, orientation="horizontal")

        box.spacing = dp(20)
        box.add_widget(self.task_field)
        box.add_widget(add_button)
        self.add_widget(box)
        self.task_field.focus = True


        self.tasks_box = TasksBox()
        scroll_box = ScrollBox()
        scroll_box.add_widget(self.tasks_box)
        self.add_widget(scroll_box)

    def get_value(self, instance, value):
        self.text_value = value
    def create_task(self, instance):
        todo = Todo()
        if len(self.text_value) > 2:
            todo.create_task(self.text_value, d.datetime.now().strftime("%Y-%m-%d %H:%M"), "Todo")
            self.add_task(todo.get_tasks())
            self.task_field.text = ""
        else:
            print("Please write a task! Contains more than 4 characters!")
        self.task_field.focus = True
    def add_task(self, tasks):
        task = tasks[len(tasks)-1]
        task_name = task["name"]
        task_id = task["id"]
        task_status = task["status"]
        task_date = task["date"]

        task_box = BoxLayout(size_hint=(1, None), height=self.btn_height)
        task_box.spacing = dp(10)
        task_name_box = Label(text=task_name, valign="middle", halign="left", size_hint=(.6, None), height=self.btn_height, color=(0, 0, 0), padding=(dp(10)))
        task_name_box.bind(size=task_name_box.setter("text_size"))
        task_name_box.bind(size=lambda instance, value: self.update_border_size(instance, value, (0, 0, 0)))

        task_id_box = Label(text=f"{task_id}", size_hint=(.1, None), height=self.btn_height, color=(1, 1, 1))
        task_id_box.bind(size=lambda instance, value: self.update_size(instance, value, (0, .6, 1)))

        task_status_box = Label(text=task_status, size_hint=(.1, None), height=self.btn_height, color=(0, 0, 0))
        task_status_box.bind(size=lambda instance, value:self.update_size(instance, value, (.5, 1, .5)))

        task_date_box = Label(text=f"{task_date}", size_hint=(.2, None), height=self.btn_height, color=(163/255, 163/255, 163/255))
        task_date_box.bind(size=lambda instance, value:self.update_border_size(instance, value, (0, 0, 0, .7)))

        task_box.add_widget(task_id_box)
        task_box.add_widget(task_status_box)
        task_box.add_widget(task_name_box)
        task_box.add_widget(task_date_box)

        self.tasks_box.add_widget(task_box)



    def update_size(self, instance, value, color):
        instance.canvas.before.clear()
        with instance.canvas.before:
            instance.canvas.before.clear()
            Color(*color)
            Rectangle(size=value, pos=instance.pos)
    def update_border_size(self, instance, value, color):
        instance.canvas.before.clear()
        with instance.canvas.before:
            instance.canvas.before.clear()
            Color(*color)
            Line(rectangle=(instance.pos[0], instance.pos[1], value[0], value[1]))

我希望每个任务都带有边框,以便画布更新每个任务的 pos。

python python-3.x kivy desktop-application
1个回答
0
投票

您已将画布更新绑定到几个小部件的大小,但大多数小部件都不会更改大小,除非您调整整个应用程序的大小。但是,每次添加新任务时

TaskBox
都会更改大小,因此将更新方法绑定到
TaskBox
的大小,并使用该更新方法循环遍历所有任务并更新每个任务。

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