嵌入在 canvas 中的元素的引用属性 (Kivy)

Reference attribute of element that is embedded in canvas (Kivy)

我试图在 canvas 中引用矩形对象的源图像。我似乎找不到可以正确引用它的正确代码。尝试使用 id 不起作用,因为无法为矩形指定一个 id,只能指定一个组。因此,我需要使用一个组,但这很复杂,因为我有几个嵌入的属性。谁能帮忙?当用户遇到类似问题时,我在网上找到了当前使用 self.canvas.get_group("firstQelement")[0].source 的解决方案。我试过使用不同的路径进入群组,包括引用 ID 和布局。

AnswerCycle 指的是预先格式化的切换按钮

Kivy 文件:

<QuestionDisplay>:
    name: "questionDisplay"
    RelativeLayout:
        canvas.before:
            Color:
                rgba: utils.get_color_from_hex('#90E0EF')
            Rectangle:
                pos: self.pos
                size: self.size
    GridLayout:
        padding: 20
        spacing: 20
        cols: 1
        size: root.width, root.height
        Title: 
            id: questionTitle
        Image:
            canvas.before:
                Color:
                    rgba: utils.get_color_from_hex('#0077B6')
                Rectangle:
                    size: self.size
                    pos: self.pos
            id: mainQuestion
            source: "empty.png"
            size_hint_y: None
            size: root.width, 195
        GridLayout:
            size_hint_y: None
            size: root.width, 200
            cols: 2
            AnswerCycle:
                id: firstQ
                canvas.after:
                    Rectangle
                        group: "firstQelement"
                        pos: self.pos
                        size: self.size
                        source: "empty.png"
            AnswerCycle:
                id: secondQ
                canvas.after:
                    Rectangle
                        group: "secondQelement"
                        pos: self.pos
                        size: self.size
                        source: "empty.png"
            AnswerCycle:
                id: fourthQ
                canvas.after:
                    Rectangle
                        group: "thirdQelement"
                        pos: self.pos
                        size: self.size
                        source: "empty.png"
            AnswerCycle:
                id: thirdQ
                canvas.after:
                    Rectangle
                        group: "fourthQelement"
                        pos: self.pos
                        size: self.size
                        source: "empty.png"

Python代码:

if Value.correctButtonNumber ==  1: self.canvas.get_group("firstQelement")[0].source = "cAnswer.png"
if Value.correctButtonNumber ==  2: self.canvas.get_group("secondQelement")[0].source = "cAnswer.png"
if Value.correctButtonNumber ==  3: self.canvas.get_group("thirdQelement")[0].source = "cAnswer.png"
if Value.correctButtonNumber ==  4: self.canvas.get_group("fourthQelement")[0].source = "cAnswer.png"

错误:

if Value.correctButtonNumber ==  1: self.canvas.get_group("firstQelement")[0].source = "cAnswer.png"
 IndexError: list index out of range

最小可重现示例:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
import random

APP_KV = """
<CanvasTest>:
    BoxLayout:
        canvas.after:
            Color:
                rgba: 0, 1, 0, 1
            Rectangle:
                group: 'rectangle'
                size: 400, 200
                pos: self.pos
            Color:
                rgba: 1, 0, 0, 1
            Ellipse:
                group: 'ellipse'
                size: 200, 100
                pos: self.pos
"""

class CanvasTest(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        print(self.BoxLayout.canvas.after.get_group('rectangle'))
    
class MainApp(App):
    def build(self):
        self.root = Builder.load_string(APP_KV)
        return CanvasTest()

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

从 KV 脚本和打印语句中删除 BoxLayout: 后,此代码可以正常工作。

这是您的代码的修改版本,它更改了 Rectanglesource 属性:

from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout

APP_KV = """
<CanvasTest>:
    BoxLayout:
        id: box
        canvas.after:
            Color:
                rgba: 0, 1, 0, 1
            Rectangle:
                group: 'rectangle'
                size: 400, 200
                pos: self.pos
            Color:
                rgba: 1, 0, 0, 1
            Ellipse:
                group: 'ellipse'
                size: 200, 100
                pos: self.pos
"""


class CanvasTest(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Clock.schedule_once(self.info, 2)

    def info(self, dt):
        rect = self.ids.box.canvas.after.get_group('rectangle')[0]
        rect.source = 'tester.png'


class MainApp(App):
    def build(self):
        self.root = Builder.load_string(APP_KV)
        return CanvasTest()


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

我将 boxid 添加到 APP_KV 中的 BoxLayout 以允许访问 BoxLayout。请注意,您不应尝试在 __init__() 方法中访问 ids,因为此时它们通常尚未设置。这就是为什么我使用 Clock.schedule_once().