您需要修改Rectangle
指令(或撤換,但修改比較容易)。
with self.canvas:
self.rect = Rectangle(source='image.png')
再後來:
self.rect.source = 'newImage.png'
至於你的問題的第二部分,問題是,圖像在Kivy在加載緩存。所以,當你保存newimage.png
並重新加載它再次,基維知道你已經加載newimage.png
。這對於Kivy應用程序來說並不是一個很好的設計。
此外,Rectangle
在on_touch_down
創造意味着你最終創造按下部件新Rectangle
每一次,所以你只需要添加更多不必要的繪圖指令。
您可能還會注意到,當您將多個這些小部件添加到佈局時,它們都會在窗口的整個大小的同一位置呈現。小部件不限制在他們的區域繪製,並且可以在應用程序的任何地方繪製。您需要確保Rectangle
指令知道在哪裏繪製,通過傳遞size
和pos
參數。
最後,不是保存圖像,而是隻顯示其中一個。這將會更有效率,並且不需要使用獨特的文件名或者與緩存系統混淆。
您絕對應該看看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 propertytilesource
。但tilesource
不是Widget
類的財產!別擔心。在kv中,當你將一個值賦給這樣一個不存在的屬性時,該屬性將自動創建。由於我們分配給屬性的值是一個字符串,Kivy會意識到我們希望這是一個StringProperty
。
通過創建此屬性,我們可以從外部影響這個小部件。我們將使用此屬性的值在稍後顯示圖像。
canvas:
就像在Python中使用with self.canvas:
一樣。
Color:
rgba: 1, 1, 1, 1
在canvas
塊內,我們可以添加繪圖指令。我們從Color
instruction開始,因爲您不知道當前設置的顏色。這種顏色會對我們展示的圖像着色,並且我們不需要任何色調,所以我們使用全白色。
Rectangle:
size: self.size
pos: self.pos
source: 'image.png'
現在我們要呈現第一張圖片。我們確保Rectangle
的大小和位置與小部件匹配。在kv中,這樣做會自動創建一個綁定。如果小部件被移動,它的大小將會改變,並且Rectangle
將自我更新以匹配。
Color:
a: 1 if self.tilesource else 0
這一次,我們知道顏色設置爲什麼。但是,我們不想在設置圖像之前繪製其他任何東西。在kv中,屬性將接受任何Python值。這意味着你可以像這樣使用ternary expressions,或者函數調用或者算術等。因此,如果self.tilesource
的計算結果爲False(就像我們在上面設置的默認值的空字符串),那麼顏色(alpha分量)的a
屬性將被設置爲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
是很重要的。就像小部件可以在應用程序的任何位置繪製一樣,它們也可以在應用程序的任何位置處理觸摸。這可以確保在動作之前觸摸實際上在我們的小部件的範圍內。 Insidecollide_point
block,我們將返回True以讓Kivy知道我們已經處理了這個接觸,並且沒有別的東西會處理它。否則,我們呼叫super()
讓默認處理程序接管。
我似乎無法使用 * self.rect.source ='newImage.png'* 與另一個類比* with self.canvas:self.rect = Rectangle(source ='image。png')* 我得到一個錯誤* AttributeError:'class'對象沒有屬性'rect'* –
在這種情況下,你的問題的一部分是你試圖添加第二個Rectangle到不同的畫布。您需要引用原始小部件以更改其上的矩形。 –
我無法獲得代碼在這些評論中很好地顯示即時將它添加到我的問題 –