Я только что подобрал Киви и столкнулся с этой проблемой. Если есть лучший способ достичь того, что я пытаюсь в целом, мне бы хотелось услышать об этом.Kivy размещает виджеты несколько иначе с помощью языка Python и Kivy. Я что-то упускаю?
Что я заметил, так это то, что когда я добавлю виджет в другой виджет, если я сделаю это через код Python, он будет немного в другом положении, чем если бы я сделал это через Kivy. Я вставлю свой код ниже (сейчас он довольно короткий), и вы можете просто попробовать его сами, и вы поймете, что я имею в виду.
client.py:
import kivy
kivy.require('1.9.1') # current kivy version
from kivy.config import Config
Config.set('graphics', 'width', '360')
Config.set('graphics', 'height', '640')
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty, NumericProperty, ReferenceListProperty
from kivy.graphics import Color, Rectangle
from kivy.clock import Clock
from kivy.vector import Vector
from random import randint
class Bird(Widget):
'''
Bird Widget defines each sprite./Test version: blue and red cards
Defined attributes:
SIZE
POSITION
(COLOR)
Upade the position of this widget individually every 0.7 seconds with 60 fps
'''
# set attributes
border_color = (1,1,1)
r = NumericProperty(0)
g = NumericProperty(0)
b = NumericProperty(0)
color = ReferenceListProperty(r, g, b) # initial color = red // maybe make it random
velocity_x = NumericProperty(0)
velocity_y = NumericProperty(-3)
velocity = ReferenceListProperty(velocity_x, velocity_y)
def __init__(self, **kwargs):
super(Bird, self).__init__(**kwargs)
self.pick_color()
# Randomly generate 0 or 1, and pick a color based on that
def pick_color(self):
color_num = randint(0,1)
if color_num == 0: # blue
self.color = (0,0,1)
elif color_num == 1: # red
self.color = (1,0,0)
# Move the widget by -3y increment at 60 fps
def increment(self, dt):
self.pos = Vector(*self.velocity) + self.pos
def move(self):
# While the sprite moves at 60 fps, the movement is "cancelled" after 0.3 seconds
# This event sequence is refreshed every 0.7 seoncds in MainApp class
move = Clock.schedule_interval(self.increment, 1.0/60.0)
stop = Clock.schedule_once(lambda dt: move.cancel(), 0.3)
class GameMain(Widget):
'''
Contains two functions: ADD_NEW_BIRD() and UPDATE().
All controls happen in this widget
Not using kivy.screen because there is only one screen used
ADD_NEW_BIRD() adds a new bird to list_of_birds AND add it as a child widget to the GameMain Widget. UPDATE() calls MOVE() (Bird Widget) and receives events
Create global variable limit = 0; if limit == 4, game over; variable accessed in update function, which checks whether the limit has been reached. If the player makes the right decision, then limit -= 1
'''
limit = 0
def add_new_bird(self):
self.new_bird = Bird(center_x=self.center_x, center_y=self.height/1.5)
print (self.center_x, self.height)
self.new_bird.pick_color()
self.add_widget(self.new_bird)
def update(self, dt):
for bird in self.children:
bird.move()
self.add_new_bird()
class MainApp(App):
def build(self):
game = GameMain()
Clock.schedule_interval(game.update, 0.7)
return game
if __name__ == '__main__':
MainApp().run()
main.kv:
#:kivy 1.9
<Bird>:
size: 70, 80
canvas:
Color:
rgb: self.border_color
Rectangle:
size: self.size
pos: self.pos
Color:
rgb: self.color
Rectangle:
size: root.width - 10, root.height - 10
pos: root.x + 5, root.y + 5
<GameMain>
Bird:
center_x: root.center_x
center_y: root.height/1.5
код делает именно то, что я хочу, чтобы это сделать (я собираюсь остановиться на Z-значениях позже) за исключением того, что самая первая карта слегка отведена влево. Я просто очень смущен, потому что center_x: root.center_x
в main.kv
не должен отличаться от Bird(center_x=self.center_x
в client.py
насколько я понимаю. Я пытался инициализировать первый экземпляр Bird()
внутри функцию инициализации, как так:
def __init__(self, **kwargs):
super(GameMain, self).__init__(**kwargs)
self.bird = Bird(center_x=self.center_x, center_y=self.height/1.5)
self.bird.pick_color()
self.add_widget(self.bird)
И проблема была все еще там! Если бы кто-нибудь мог объяснить, что происходит/что я делаю неправильно, и, возможно, даже предложить лучший способ приблизиться к этому, я был бы признателен.
На всякий случай вам любопытно, мне нужно добавить виджеты непосредственно из кода Python, потому что мне нужно приложение для постоянного создания новой карты с постоянным временным интервалом. Однако первая карта инициализируется в файле Kivy для простоты. Чтобы быть справедливым, это работает очень хорошо, за исключением смещения. И, наконец, я не использую макет, потому что не был уверен, какой из них использовать ... Я немного положил руки на FloatLayout, но, похоже, это не решило проблему.
Спасибо. Я закончил использовать обходной путь, но зная, что это спасло бы меня от головной боли. Кроме того, эта часть о том, чтобы не смешивать слишком много киви и питона - я вижу эту проблему прямо сейчас, с Popups. Я бы хотел, чтобы это идеальное «разделение» (kivy обрабатывает все элементы интерфейса UI, питон управляет логикой), но поскольку я добавляю виджеты динамически довольно часто, я в конечном итоге использую python больше. Может быть, я должен полностью удалить киви файл. – spicypumpkin