Kivy小部件不移动

时间:2019-02-17 13:10:04

标签: python kivy

程序运行时,ScreenManager会显示主屏幕,我在上面添加了白色的小square(Ball)

小工具球应该在移动,但我不知道为什么它仍然是静态的。 更新方法有效,但是窗口小部件的位置未更新。我试图四处移动,但没有效果。

如果有人可以帮助我了解我在哪里错了,那就太好了。非常感谢。

import kivy
kivy.require('1.10.1')
from kivy.app import App
from kivy.core.window  import Window
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.graphics import Rectangle
from kivy.uix.widget import Widget
from kivy.properties import ListProperty
from kivy.clock import Clock

# simple Screen on which the ball should move
class Main(Screen):
    def __init__(self, **kwargs):
        super(Main, self).__init__(**kwargs)
        self.add_widget(Ball())
        with self.canvas.before:
            Rectangle(source = 'BG1.png',
                      size = Window.size,
                      pos = self.pos)

# the Ball should be bouncing around
class Ball(Widget):
    velocity = ListProperty([10, 15])
    def __init__(self, **kwargs):
        super(Ball, self).__init__(**kwargs)
        Clock.schedule_interval (self.update, 1 / 60)

        with self.canvas:
            Rectangle (color=[0, 0, 0, 1],
                       size=(10, 10),
                       pos = self.pos)

    def update(self, *args):
        print('wtf')
        self.x += self.velocity[0]
        self.y += self.velocity[1]

        if self.x < 0 or (self.x + self.width) > Window.width:
            self.velocity[0] *= -1
        if self.y < 0 or (self.y + self.height) > Window.height:
            self.velocity[1] *= -1

Window.size = (400, 300)
sm = ScreenManager()
sm.add_widget(Main(name = 'main'))

class Bubble(App):
    def build(self):
        return sm

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

3 个答案:

答案 0 :(得分:2)

谢谢Embryo和John,您的回答使我找到了正确的答案。我在此博客上找到了此代码。全部解决:Kivy blog

from kivy.uix.widget import Widget
from kivy.graphics import Rectangle, Color

class CornerRectangleWidget(Widget)
    def __init__(self, **kwargs):
        super(CornerRectangleWidget, self).__init__(**kwargs)

        with self.canvas:
            Color(1, 0, 0, 1)  # set the colour to red
            self.rect = Rectangle(pos=self.center,
                                  size=(self.width/2.,
                                        self.height/2.))

        self.bind(pos=self.update_rect,
                  size=self.update_rect)

    def update_rect(self, *args):
        self.rect.pos = self.pos
        self.rect.size = self.size

答案 1 :(得分:1)

问题在于,当您在python中(而不是在Canvas中设置kv指令时,不会获得kv为您提供的自动绑定。因此,您在Rectangle方法中定义的Ball.__init__()在其pos时刻被pos定义为Ball的{​​{1}}(即是[0,0]),并且不会自动更改。您可以自己进行更新来解决此问题。首先,在您的__init__()中,将您的Ball.__init__()块更改为:

with self.canvas

一个更改是定义 with self.canvas: Color(0,0,0,1) self.rect = Rectangle (size=(10, 10), pos = self.pos) ,第二个更改是创建对Color的引用。然后在您的更新方法中添加以下行:

Rectangle

这将移动具有Ball位置的矩形。

此外,您的self.rect.pos = self.pos 方法存在一些问题,因为update的{​​{1}}与size的大小相同。它不是您在Ball中提供的Window

答案 2 :(得分:0)

好吧,这是怎么回事...

实例化Ball小部件时,您一次绘制了矩形。
这是您在左下角看到的。
之后,您可以移动小部件,但是不会再次绘制。

如果您在更新功能中print(self.pos),您会发现它正在移动...