【问题标题】:Using ids to change properties of widgets in Kivy在 Kivy 中使用 id 更改小部件的属性
【发布时间】:2021-10-11 18:20:46
【问题描述】:

我最近开始在 Kivy 开展一个项目,以便更好地了解该库。当我开始在我的 python 代码中管理我的 kv 脚本中的 ID 时遇到问题时,我开始设置主屏幕。

总而言之,我目前正在编写使我的播放器 (resources/player1.png) 指向光标的代码。为了获得光标的位置,我使用了 Touch 小部件并在我单击时让它打印坐标。然后我想将此信息传递给一个函数,该函数将接收它并相应地旋转图像(我知道我在该区域还有工作要做)。但是,当我尝试让图像的 id (id: player) 旋转时,我最终得到KeyError: 'player'。我尝试通过打印 self.ids 来列出 id,但没有列出,如输出所示(错误消息前的空括号)。我四处寻找这个错误并查看了Kivy's docs on ids,但我找不到任何东西。

这是我目前拥有的代码:

from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.widget import Widget


class Window1(Screen):
    pass

class Window2(Screen):
    pass

class WindowManager(ScreenManager):
    pass

class Touch(Widget):
    def aim(self):
        print(self.ids)
        player_id = self.ids['player']
        player_id.rotate(90.0, 0.0, 0.0, 0.0)

    def on_touch_down(self, touch):
        print(touch)
        self.aim()

Kv 文件:

#: import NoTransition kivy.uix.screenmanager.SlideTransition

WindowManager:
    Window1:
    Window2:

<Window1>:
    id: win1
    name: 'w1'

    RelativeLayout:
        orientation: 'vertical'
        size: root.width, root.height

        Label:
            text: 'TITLE'
            font_size: 40
            size_hint: .3, .2
            pos_hint: {'top': 0.7, 'right': 2/3}
        Button:
            size_hint: .3, .2
            pos_hint: {'top': 0.5, 'right': 2/3}
            text: 'START'
            font_size: 40
            on_release:
                app.root.transition = NoTransition(duration=0)
                app.root.current = 'w2'


<Window2>:
    id: win2
    name: 'w2'
    Touch:
        canvas.before:
            Color:
                rgb: (.1, .1, .1)
            Rectangle:
                size: self.size
        canvas:

            Color:
                rgb: (1, 1, 1)
            Rectangle:
                id: player
                source: 'resources/player1.png'
                size: 66, 99
                pos: (self.width/2-33, self.height/2-49.5)

输出:

[INFO   ] [Logger      ] Record log in C:\Users\daqna\.kivy\logs\kivy_21-10-11_31.txt
[INFO   ] [deps        ] Successfully imported "kivy_deps.angle" 0.3.0
[INFO   ] [deps        ] Successfully imported "kivy_deps.glew" 0.3.0
[INFO   ] [deps        ] Successfully imported "kivy_deps.sdl2" 0.3.1
[INFO   ] [Kivy        ] v2.0.0
[INFO   ] [Kivy        ] Installed at "C:\Users\daqna\PycharmProjects\game\venv\lib\site-packages\kivy\__init__.py"
[INFO   ] [Python      ] v3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)]
[INFO   ] [Python      ] Interpreter at "C:\Users\daqna\PycharmProjects\game\venv\Scripts\python.exe"
[INFO   ] [Factory     ] 186 symbols loaded
[INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2 (img_pil, img_ffpyplayer ignored)
[INFO   ] [Window      ] Provider: sdl2
[INFO   ] [GL          ] Using the "OpenGL" graphics system
[INFO   ] [GL          ] GLEW initialization succeeded
[INFO   ] [GL          ] Backend used <glew>
[INFO   ] [GL          ] OpenGL version <b'4.6.0 - Build 30.0.100.9922'>
[INFO   ] [GL          ] OpenGL vendor <b'Intel'>
[INFO   ] [GL          ] OpenGL renderer <b'Intel(R) UHD Graphics'>
[INFO   ] [GL          ] OpenGL parsed version: 4, 6
[INFO   ] [GL          ] Shading version <b'4.60 - Build 30.0.100.9922'>
[INFO   ] [GL          ] Texture max size <16384>
[INFO   ] [GL          ] Texture max units <32>
[INFO   ] [Window      ] auto add sdl2 input provider
[INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
[INFO   ] [Text        ] Provider: sdl2
[INFO   ] [GL          ] NPOT texture support is available
[INFO   ] [Base        ] Start application main loop
<MouseMotionEvent spos=(0.71625, 0.43666666666666665) pos=(573.0, 262.0)>
{}
[INFO   ] [Base        ] Leaving application in progress...
 Traceback (most recent call last):
   File "C:\Users\daqna\PycharmProjects\game\main.py", line 35, in <module>
     GameApp().run()
   File "C:\Users\daqna\PycharmProjects\game\venv\lib\site-packages\kivy\app.py", line 950, in run
     runTouchApp()
   File "C:\Users\daqna\PycharmProjects\game\venv\lib\site-packages\kivy\base.py", line 582, in runTouchApp
     EventLoop.mainloop()
   File "C:\Users\daqna\PycharmProjects\game\venv\lib\site-packages\kivy\base.py", line 347, in mainloop
     self.idle()
   File "C:\Users\daqna\PycharmProjects\game\venv\lib\site-packages\kivy\base.py", line 391, in idle
     self.dispatch_input()
   File "C:\Users\daqna\PycharmProjects\game\venv\lib\site-packages\kivy\base.py", line 342, in dispatch_input
     post_dispatch_input(*pop(0))
   File "C:\Users\daqna\PycharmProjects\game\venv\lib\site-packages\kivy\base.py", line 248, in post_dispatch_input
     listener.dispatch('on_motion', etype, me)
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\daqna\PycharmProjects\game\venv\lib\site-packages\kivy\core\window\__init__.py", line 1412, in on_motion
     self.dispatch('on_touch_down', me)
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\daqna\PycharmProjects\game\venv\lib\site-packages\kivy\core\window\__init__.py", line 1428, in on_touch_down
     if w.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\daqna\PycharmProjects\game\venv\lib\site-packages\kivy\uix\screenmanager.py", line 1198, in on_touch_down
     return super(ScreenManager, self).on_touch_down(touch)
   File "C:\Users\daqna\PycharmProjects\game\venv\lib\site-packages\kivy\uix\widget.py", line 545, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\daqna\PycharmProjects\game\venv\lib\site-packages\kivy\uix\relativelayout.py", line 297, in on_touch_down
     ret = super(RelativeLayout, self).on_touch_down(touch)
   File "C:\Users\daqna\PycharmProjects\game\venv\lib\site-packages\kivy\uix\widget.py", line 545, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\daqna\PycharmProjects\game\main.py", line 24, in on_touch_down
     self.aim()
   File "C:\Users\daqna\PycharmProjects\game\main.py", line 19, in aim
     player_id = self.ids['player']
 KeyError: 'player'

Process finished with exit code 1

如果有一个非常明显的解决方案,我很抱歉,我是 kivy 的新手,不了解 id,老实说 OOP 非常好。感谢您的反馈。

【问题讨论】:

    标签: python oop kivy kivy-language


    【解决方案1】:

    很遗憾,您不能将id 分配给画布指令。另一种方法是让您的Touch 小部件扩展Image 并旋转整个小部件。为此,请将kv&lt;Window2&gt; 修改为:

    <Window2>:
        id: win2
        name: 'w2'
        Touch:
            id: player
            source: 'resources/player1.png'
            size_hint: None, None
            size: 66, 99
            pos: (root.width/2-33, root.height/2-49.5)
    
            canvas.before:
                PushMatrix
                Rotate:
                    angle: self.rotate
                    axis: 0,0,1
                    origin: self.center
            canvas.after:
                PopMatrix
    

    并将Touch 小部件修改为:

    class Touch(Image):
        rotate = NumericProperty(0)  # the angle for rotating the Image
    
        def aim(self):
            self.rotate += 90.0
    
        def on_touch_down(self, touch):
            print(touch)
            self.aim()
    

    【讨论】:

      猜你喜欢
      • 2018-01-12
      • 1970-01-01
      • 2019-01-21
      • 1970-01-01
      • 1970-01-01
      • 2016-06-17
      • 2016-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多