을 당신은 Rectangle
명령을 수정 (또는 제거하고 교체해야하지만 수정이) 쉽게 :.
with self.canvas:
self.rect = Rectangle(source='image.png')
그리고 나중에 :
질문의 두 번째 부분에 관해서는
self.rect.source = 'newImage.png'
, 문제는 그래서 당신은 newimage.png
을 저장하고 다시로드 할 때. 이미지가 Kivy에 로딩에 캐시이다 Kivy는 이미 newimage.png
을로드했음을 알고 있습니다. 이것은 Kivy 앱을위한 좋은 디자인이 아닙니다.
on_touch_down
에 Rectangle
을 작성하면 위젯을 누를 때마다 새 Rectangle
이 작성되므로 더 많은 불필요한 그리기 지침을 추가하기 만하면됩니다.
위젯을 여러 개 레이아웃에 추가하면 모두 같은 크기로 전체 창의 크기로 렌더링됩니다. 위젯은 자신의 영역에서 그리기가 제한되지 않으며 앱 내 어디에서나 그릴 수 있습니다. size
및 pos
매개 변수를 전달하여 Rectangle
명령어가 어디에서 그릴지를 알고 있어야합니다.
마지막으로 이미지를 저장하는 대신 다른 이미지 위에 표시 할 수 있습니다. 이것은 훨씬 더 효율적이며 고유 한 파일 이름을 사용하거나 캐싱 시스템을 망칠 필요가 없습니다.
위젯을 디자인하고 앱을 레이아웃하는 데 훨씬 쉽게 사용할 수 있으므로 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
클래스의 자산이 아닙니다! 걱정 마. kv에서 이와 같이 존재하지 않는 속성에 값을 할당하면 해당 속성이 자동으로 만들어집니다. 속성에 할당 할 값은 문자열이므로 Kivy는이 값이
StringProperty
이되기를 바랄 것입니다.
이 속성을 만들면 외부에서이 위젯에 영향을 줄 수 있습니다. 나중에이 속성의 값을 사용하여 이미지를 표시합니다.
canvas:
파이썬의 클래스에서 with self.canvas:
을 사용하는 것과 같습니다.
Color:
rgba: 1, 1, 1, 1
블록 내에서 도면 명령을 추가 할 수 있습니다. 현재 색상이 무엇인지 알 수 없기 때문에 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 (빈 문자열, 위에서 설정 한 기본값)와 같은 경우 색상 (알파 구성 요소) a
속성
Rectangle:
size: self.size
pos: self.pos
source: self.tilesource
마지막으로 우리는 선택한 이미지를 렌더링합니다.
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
블록이 있으면 True를 반환하여 Kivy가이 터치를 처리했다는 사실을 알게하고 처리해야하는 것이 없음을 알립니다. 그렇지 않으면
super()
을 호출하여 기본 처리기가 처리하도록합니다.
* self.rectsource = 'newImage.png'* * self.canvas와 다른 클래스에 * 사용하지 않는 것 같습니다 : self.rect = Rectangle (source = 'image.png ') * 오류가 발생합니다. * AttributeError :'class '객체에'rect '속성이 없습니다. * –
이 경우 두 번째 사각형을 다른 캔버스에 추가하려고 할 때 문제가 발생했습니다. 원래 위젯을 참조하여 사각형 위젯을 변경해야합니다. –
나는이 코멘트에 멋지게 보여줄 수있는 코드를 얻지 못한다. 내 질문에 그것을 추가하려고한다. –