python kivy canvas_python - Python Kivy Canvas不会更新 - 堆栈内存溢出

您需要修改Rectangle指令(或删除并替换,但修改起来更容易):

with self.canvas:

self.rect = Rectangle(source='image.png')

然后再:

self.rect.source = 'newImage.png'

至于问题的第二部分,问题在于在Kivy中加载图像时会对其进行缓存。 因此,当您保存newimage.png并再次重新加载时,Kivy知道您已经加载了newimage.png 。 对于Kivy应用程序来说,这并不是一个很好的设计。

同样,在on_touch_down创建Rectangle意味着每次按下该小部件时最终都会创建一个新的Rectangle ,因此您只需添加越来越多的不必要的绘图指令即可。

您可能还会注意到,当您将多个这些小部件添加到布局中时,它们全部以窗口的完整大小呈现在同一位置。 小部件不限于在其区域内绘制,并且可以在应用程序内的任何位置绘制。 您需要通过传递Rectangle指令的size和pos参数来确保其知道在哪里绘制。

最后,除了保存图像,您还可以在另一个图像上显示一个图像。 这将更加高效,并且不需要使用唯一的文件名或将缓存系统弄乱。

您绝对应该看一下Kivy语言(kv),因为它在设计小部件和布局应用程序时非常容易使用。

这是使用kv执行此操作的示例:

:

tilesource: ''

canvas:

Color:

rgba: 1, 1, 1, 1

Rectangle:

size: self.size

pos: self.pos

source: 'image.png'

Color:

a: 1 if self.tilesource else 0

Rectangle:

size: self.size

pos: self.pos

source: self.tilesource

现在,我将解释所有这些功能。

:

这是一个类规则,因为名称被<>包围。 它将应用于TileWidget所有实例。

tilesource: ''

在这里,我们设置属性 tilesource 的值 。 但是tilesource不是Widget类的属性! 别担心。 在kv中,当您为这样的不存在属性分配值时,该属性将自动创建。 由于我们要分配给该属性的值是一个字符串,因此Kivy将意识到我们希望它是一个StringProperty 。

通过创建此属性,我们可以从外部影响此小部件。 我们稍后将使用此属性的值来显示图像。

canvas:

就像with self.canvas:来自Python类。

Color:

rgba: 1, 1, 1, 1

在canvas块内,我们可以添加绘图指令。 我们从Color指令开始,因为您不知道当前设置的颜色。 该颜色将着色我们显示的图像,并且我们不需要任何着色,因此我们使用全白色。

Rectangle:

size: self.size

pos: self.pos

source: 'image.png'

现在,我们将渲染第一张图像。 我们确保Rectangle的大小和pos与小部件匹配。 在kv中,这样做会自动创建绑定。 如果小部件到处移动,其大小将改变,并且Rectangle将更新以匹配。

Color:

a: 1 if self.tilesource else 0

这次,我们知道颜色设置为什么。 但是,在设置图像之前,我们不想绘制其他任何东西。 在kv中,属性将接受任何Python值。 这意味着您可以使用像这样的三元表达式 ,函数调用或算术等。因此,如果self.tilesource计算结果为False(如空字符串,即我们在上面设置的默认值),那么颜色的a属性( alpha分量)将设置为0,否则将为1。

Rectangle:

size: self.size

pos: self.pos

source: self.tilesource

最后,我们渲染选定的图像。

现在,要创建小部件本身,我们只需要一点Python:

class TileWidget(Widget):

def on_touch_down(self, touch):

if self.collide_point(*touch.pos):

self.tilesource = '64x64tile.png'

return True

return super(TileWidget, self).on_touch_down(touch)

就像小部件可以在应用程序中的任何位置绘制一样,它们也可以处理应用程序中任何位置的触摸。 这样可以确保在执行操作之前,触摸实际上在小部件的范围内。 在 collide_point块中,我们将返回True,以让Kivy知道我们已经处理了此触摸,并且没有其他任何处理。 否则,我们调用super()来让默认处理程序接管。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值