#python #oop #kivy #kivy-language
Вопрос:
Я недавно начал работать над проектом в Киви, чтобы лучше понять библиотеку. Я дошел до определенного момента настройки главного экрана, когда у меня начались проблемы с управлением идентификаторами из моего сценария kv в моем коде python.
Подводя итог, я в настоящее время работаю над кодом, который заставит мой плеер (ресурсы/player1.png) указывать на курсор. Чтобы определить положение курсора, я использую сенсорный виджет и печатаю координаты при нажатии. Затем я хочу передать эту информацию в функцию, которая примет ее и соответствующим образом повернет изображение (я знаю, что мне еще предстоит поработать в этой области). Однако, когда я пытаюсь получить идентификатор изображения (идентификатор: плеер) для поворота, я в конечном итоге получаю KeyError: 'player'
. Я попытался перечислить идентификаторы, напечатав self.id, но ни один из них не указан, как видно на выходных данных (пустые фигурные скобки перед сообщениями об ошибках). Я искал эту ошибку и просмотрел документы Киви по идентификаторам, но ничего не нашел.
Вот код, который у меня есть в настоящее время:
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:Usersdaqna.kivylogskivy_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:UsersdaqnaPycharmProjectsgamevenvlibsite-packageskivy__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:UsersdaqnaPycharmProjectsgamevenvScriptspython.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:UsersdaqnaPycharmProjectsgamemain.py", line 35, in <module>
GameApp().run()
File "C:UsersdaqnaPycharmProjectsgamevenvlibsite-packageskivyapp.py", line 950, in run
runTouchApp()
File "C:UsersdaqnaPycharmProjectsgamevenvlibsite-packageskivybase.py", line 582, in runTouchApp
EventLoop.mainloop()
File "C:UsersdaqnaPycharmProjectsgamevenvlibsite-packageskivybase.py", line 347, in mainloop
self.idle()
File "C:UsersdaqnaPycharmProjectsgamevenvlibsite-packageskivybase.py", line 391, in idle
self.dispatch_input()
File "C:UsersdaqnaPycharmProjectsgamevenvlibsite-packageskivybase.py", line 342, in dispatch_input
post_dispatch_input(*pop(0))
File "C:UsersdaqnaPycharmProjectsgamevenvlibsite-packageskivybase.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:UsersdaqnaPycharmProjectsgamevenvlibsite-packageskivycorewindow__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:UsersdaqnaPycharmProjectsgamevenvlibsite-packageskivycorewindow__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:UsersdaqnaPycharmProjectsgamevenvlibsite-packageskivyuixscreenmanager.py", line 1198, in on_touch_down
return super(ScreenManager, self).on_touch_down(touch)
File "C:UsersdaqnaPycharmProjectsgamevenvlibsite-packageskivyuixwidget.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:UsersdaqnaPycharmProjectsgamevenvlibsite-packageskivyuixrelativelayout.py", line 297, in on_touch_down
ret = super(RelativeLayout, self).on_touch_down(touch)
File "C:UsersdaqnaPycharmProjectsgamevenvlibsite-packageskivyuixwidget.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:UsersdaqnaPycharmProjectsgamemain.py", line 24, in on_touch_down
self.aim()
File "C:UsersdaqnaPycharmProjectsgamemain.py", line 19, in aim
player_id = self.ids['player']
KeyError: 'player'
Process finished with exit code 1
Извините, если есть действительно очевидное решение, я новичок в киви и не очень хорошо понимаю идентификаторы и, честно говоря, ООП. Спасибо за отзыв.
Ответ №1:
К сожалению, вы не можете назначить id
инструкцию для холста. Другой подход заключается в том, чтобы просто Touch
расширить Image
и повернуть весь виджет. Для этого измените свой kv
для <Window2>
:
<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()