gpt4 book ai didi

Python Kivy Canvas 不会更新

转载 作者:太空宇宙 更新时间:2023-11-04 10:29:29 24 4
gpt4 key购买 nike

我正在使用 64x64 的图 block 创建一个“ map 编辑器”。单击并更改位置处的图 block 时,我需要更新 Canvas 。我最初用

设置 Canvas
with self.canvas:
Rectangle(source = 'image.png')

在一节课中,然后在我的 touch_down 课中我打电话

with self.canvas:
Rectangle(source = 'newImage.png')

在我更改图像以更新它之后。

我已经能够让它更新,但我每次都必须创建一个新图像,它似乎不会更新,因为我已经添加了那个带有特定源图像的矩形,并且没有看到图像已经变了?

回应 Ryan P

仍然没有。我试过了

Class mypaintwidget(Widget): #This is added as a widget to my layout
def on_touch_down(self, touch):
with self.canvas:
self.rect = Rectangle(source = 'image.png')
tilepng = pil.open('64x64tile.png') #pil is Python Image Library
tilemap = pil.open('image.png')
tilemap.paste(tilepng,location)
tilemap.save('newimage.png')
self.rect.source = 'newimage.png'

只会更新一次。然后什么都没有(但仍会保存该图像,但不会显示给我。

最佳答案

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

with self.canvas:
self.rect = Rectangle(source='image.png')

然后:

self.rect.source = 'newImage.png'

至于问题的第二部分,问题是图像在加载到 Kivy 时会被缓存。所以当你保存 newimage.png然后重新加载它,Kivy 知道你已经加载了 newimage.png .对于 Kivy 应用程序来说,这并不是一个好的设计。

此外,创建 Rectangleon_touch_down意味着你最终创建了一个新的 Rectangle每次按下小部件时,您只会添加越来越多不必要的绘图指令。

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

最后,您可以只显示一张叠加在另一张上,而不是保存图片。这将更加高效,并且不需要使用唯一的文件名或扰乱缓存系统。

你绝对应该看看 Kivy language (kv)因为使用它设计小部件和布置您的应用程序要容易得多。

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

<TileWidget>:
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>:

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

    tilesource: ''

我们在这里 setting the value of the property tilesource .但是tilesource不是 Widget 上的属性类(class)!不用担心。在 kv 中,当你像这样给一个不存在的属性赋值时,该属性将被自动创建。由于我们分配给属性的值是一个字符串,Kivy 会意识到我们希望它是一个 StringProperty 。 .

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

    canvas:

就像使用with self.canvas:一样来自 Python 中的类。

        Color:
rgba: 1, 1, 1, 1

canvas 里面 block ,我们可以添加绘图说明。我们从 Color instruction 开始,因为您不知道当前设置的颜色是什么。这种颜色将为我们显示的图像着色,而我们不需要任何着色,因此我们使用全白。

        Rectangle:
size: self.size
pos: self.pos
source: 'image.png'

现在我们要渲染第一张图片。我们确保 Rectangle的大小和位置与小部件匹配。在 kv 中,这样做会自动创建一个绑定(bind)。如果小部件四处移动,它的大小将会改变,并且 Rectangle将更新自身以匹配。

        Color:
a: 1 if self.tilesource else 0

这一次,我们知道颜色设置为什么。但是,在设置图像之前,我们不想绘制任何其他内容。在 kv 中,属性将接受任何 Python 值。这意味着您可以使用 ternary expressions像这个,或函数调用,或算术等。所以如果 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 很重要处理触摸时。就像小部件可以在应用程序中的任何地方绘制一样,它们也可以处理应用程序中任何地方的触摸。这确保触摸在操作之前实际上在我们的小部件的范围内。 内部 collide_point block ,我们将返回 True 让 Kivy 知道我们已经处理了这个触摸,没有其他东西应该处理它。否则,我们调用 super() 让默认处理程序接管。

关于Python Kivy Canvas 不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27712809/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com