我正在尝试了解如何使用 Kivy - 特别是画布。我或多或少了解如何移动和调整已经绘制的矩形的大小,但我无法让矩形改变颜色。这是我的代码:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Rectangle, Color
class CanvasWidget(Widget):
def __init__(self, **kwargs):
super(CanvasWidget, self).__init__(**kwargs)
self.click_occured = False
with self.canvas:
Color(0, 1, 0)
self.background = Rectangle(pos=self.pos, size=self.size)
Color(1, 1, 1)
self.rect1 = Rectangle(pos=self.pos, size=(self.width/2, self.height/2))
Color(0, 0, 1)
self.rect2 = Rectangle(pos=self.pos, size=(self.width/4, self.height/4))
self.bind(pos = self.update_rect, size = self.update_rect)
def update_rect(self, *args):
self.background.pos = self.pos
self.background.size = self.size
if not self.click_occured:
self.rect1.pos = self.pos
else:
self.rect1.pos = self.x + self.width/8, self.y + self.height/8
self.rect1.size = (self.width/2, self.height/2)
self.rect2.pos = self.pos
self.rect2.size = (self.width/4, self.height/4)
def on_touch_down(self, touch):
self.click_occured = True
self.rect1.pos = self.x + self.width/8, self.y + self.height/8
#also, change rect1's color from white to red
class CanvasApp(App):
def build(self):
return CanvasWidget()
CanvasApp().run()
代替
on_touch_down
方法末尾的注释,我想将 rect1
的颜色更改为红色。它必须是对现有矩形的更改,而不是创建新矩形,因为我希望它保留在rect2
后面,并且我不想手动重绘后者。
如果可能的话,我希望在不使用 kv 语言的情况下实现这一目标,因为我希望能够在代码运行时动态创建矩形、标签等,而这对于 kv 语言似乎不方便。
您可以使用图形指令组来完成您想要的事情。首先,为涉及的画布指令创建一个
InstructionGroup
,如下所示:
# create an instruction group for the white Rectangle
self.grp1 = InstructionGroup()
self.grp1.add(Color(1, 1, 1))
self.rect1 = Rectangle(pos=self.pos, size=(self.width/2, self.height/2))
self.grp1.add(self.rect1)
然后使用
self.canvas.add(self.grp1)
将该组添加到画布。
然后您可以通过删除/添加指令来修改该组:
self.grp1.remove(self.grp1.children[0]) # remove the color instruction
self.grp1.insert(0, Color(1, 0, 0)) # insert the new color
这是使用此方法的代码的修改版本:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Rectangle, Color, InstructionGroup
class CanvasWidget(Widget):
def __init__(self, **kwargs):
super(CanvasWidget, self).__init__(**kwargs)
self.click_occured = False
# create an instruction group for the white Rectangle
self.grp1 = InstructionGroup()
self.grp1.add(Color(1, 1, 1))
self.rect1 = Rectangle(pos=self.pos, size=(self.width/2, self.height/2))
self.grp1.add(self.rect1)
with self.canvas:
Color(0, 1, 0)
self.background = Rectangle(pos=self.pos, size=self.size)
self.canvas.add(self.grp1) # add the instruction group to the canvas
Color(0, 0, 1)
self.rect2 = Rectangle(pos=self.pos, size=(self.width/4, self.height/4))
self.bind(pos = self.update_rect, size = self.update_rect)
def update_rect(self, *args):
self.background.pos = self.pos
self.background.size = self.size
if not self.click_occured:
self.rect1.pos = self.pos
else:
self.rect1.pos = self.x + self.width/8, self.y + self.height/8
self.rect1.size = (self.width/2, self.height/2)
self.rect2.pos = self.pos
self.rect2.size = (self.width/4, self.height/4)
def on_touch_down(self, touch):
self.click_occured = True
self.grp1.remove(self.grp1.children[0]) # remove the color instruction
self.grp1.insert(0, Color(1, 0, 0)) # insert the new color
self.rect1.pos = self.x + self.width/8, self.y + self.height/8
#also, change rect1's color from white to red
class CanvasApp(App):
def build(self):
return CanvasWidget()
CanvasApp().run()