类中的Palete是button,它与Paint类中移除画布内容的方法绑定在一起。我认为,解决方法是使用自定义事件。我对事件没有经验,也不了解kivy手册中的描述。我需要保持班级的结构。你能帮帮我吗?在
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.graphics import Color, Rectangle
from functools import partial
class Paint(Widget):
def __init__(self, palete,**kwargs):
# make sure we aren't overriding any important functionality
super(Paint, self).__init__(**kwargs)
self.palete = palete
self.contents = []
def on_touch_down(self, touch):
color = self.palete.act_col
with self.canvas:
Color(color[0], color[1], color[2])
sqr = Rectangle(pos = (touch.x, touch.y), size=(20, 40))
self.contents.append(sqr)
class Palete(BoxLayout):
def __init__(self, **kwargs):
super(Palete, self).__init__(**kwargs)
self.act_col= (1, 0, 0)
self.licol =[]
self.licol.append((1, 0, 0))
self.licol.append((0, 1, 0))
self.layout = BoxLayout(size_hint=(1, None), height=50)
for i in range(0, len(self.licol)):
but = Button( id = str(i))
col = self.licol[i]
but.background_normal = ''
but.background_color = (col[0], col[1], col[2], 1)
act = partial(self.SetColor, but.id)
but.bind(on_press=act)
self. layout.add_widget(but)
but = Button(text="<--",on_press = self.ClearContents)
self.layout.add_widget(but)
def SetColor(self,_col, h):
ind = int(_col)
self.act_col = self.licol[ind]
pass
def ClearContents(self, obj):
if len(self.contents)!= 0:
self.canvas.remove(self.contents[-1])
self.contents = self.contents[:-1]
class MyPaintApp(App):
def build(self):
root = BoxLayout(orientation='vertical')
self.palete = Palete()
self.paint =Paint(self.palete)
root.add_widget(self.paint)
root.add_widget(self.palete.layout)
return root
if __name__ == '__main__':
MyPaintApp().run()
canvas
和contents
是Paint
类的属性,您正试图从Palate
类访问它。在如果不想更改结构,可以将
Paint
类的引用传递给Palete
类:我认为您应该从实现画布的类中删除对象以保留封装。另一个选项是将回调移到
^{pr2}$Paint
类,并将on_press
事件绑定到它(来自Paint类):使用
list.pop
而不是切片从列表中删除最后一项。它更具可读性,而且不必每次都复制列表。在请参考详细说明和示例。在
重载方法__
油漆等级
1。增加Kivy属性
由于您将访问调色板和内容,我们声明如下:
^{pr2}$2。安丘触地事件
默认情况下,触摸事件被调度到所有当前显示的小部件。这意味着无论触摸事件是否发生在它们的物理区域内,小部件都会接收到触摸事件。Kivy将touch事件发送到所有widget,并让它们决定如何对它们做出反应。如果您只想响应widget/按钮内的触摸事件,则必须使用自碰撞点方法。当它发生冲突时,你应该只得到一个widget/按钮。在
在下面的代码片段中,我们重写了Widget类的on_touch_down()方法。在这里,我们检查触摸与我们的小部件的碰撞。在
如果触摸落在我们的小部件中,我们在画布上创建一个正方形并返回True,表示我们已经使用了触摸,不希望它进一步传播。在
最后,如果touch落在我们的widget之外,我们使用super(Paint,self)调用原始事件,并返回结果。这允许触摸事件传播继续进行 通常都发生过。在
调色板类
3。act_col-列表属性
因为act_col将在类Paint中访问,所以我们将其声明为Kivy ListProperty。在
4。嵌套BoxLayout-已删除
因为Palette类是一个BoxLayout,所以我们不需要嵌套的BoxLayout。因此,它被移除。在
5。新闻发布会
传递给回调的唯一参数是我们绑定到的对象,即按钮。在
MyPaintApp类
6。生成方法
我们没有把所有的东西放在类MyPaintApp的构建方法中,而是将它们移到类Painting中。我们还必须声明类的对象和调色板。在
类喷漆(方框布局): 调色板=对象属性(无) 绘制=对象属性(无)
示例
在主.py在
输出
相关问题 更多 >
编程相关推荐