为什么我需要创建一个新的行实例,而不是在Kivy中简单地更新或添加和删除它
我试图用鼠标从窗口的一个点拖到另一个点来画一条线。我还希望在拖动时表示线。就像用旧画笔画一条线 我的问题是,我只能通过不断删除旧行并向画布添加新的顶点指令来实现这一点。但是,我无法更新现有说明。甚至不添加和删除相同的指令。它必须是Line的一个新实例。通过运行以下代码,您可以看到我想要的结果。如果您尝试使用注释行运行它,它将不再工作为什么我需要创建一个新的行实例,而不是在Kivy中简单地更新或添加和删除它,kivy,Kivy,我试图用鼠标从窗口的一个点拖到另一个点来画一条线。我还希望在拖动时表示线。就像用旧画笔画一条线 我的问题是,我只能通过不断删除旧行并向画布添加新的顶点指令来实现这一点。但是,我无法更新现有说明。甚至不添加和删除相同的指令。它必须是Line的一个新实例。通过运行以下代码,您可以看到我想要的结果。如果您尝试使用注释行运行它,它将不再工作 from kivy.app import App from kivy.uix.relativelayout import RelativeLayout from k
from kivy.app import App
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import Line
class MyCanvas(RelativeLayout):
def on_touch_down(self, touch):
with self.canvas:
self.line = Line(points=[touch.x,touch.y,touch.x+1,touch.y+1])
self.bind(on_touch_move=self.update_line, on_touch_up=self.end_line)
return True
def update_line(self, instance, touch):
self.line.points[2] = touch.x
self.line.points[3] = touch.y
self.canvas.remove(self.line)
# self.canvas.add(self.line) # - this doesn't work
# self.canvas.ask_update() # - not even using this
with self.canvas:
self.line = Line(points=self.line.points) # this works
def end_line(self, instance, touch):
self.unbind(on_touch_move=self.update_line)
self.unbind(on_touch_up=self.end_line)
self.line.points[2] = touch.x
self.line.points[3] = touch.y
self.canvas.remove(self.line)
# self.canvas.add(self.line) # - this doesn't work
# self.canvas.ask_update() #- not even using this
self.canvas.add(Line(points=self.line.points)) # this way works
class ExampleApp(App):
def build(self):
return MyCanvas()
ExampleApp().run()
我还尝试使用Kivy属性作为颜色说明的建议。它不起作用,但确实存在。我正在努力解决同样的问题。我从kivy/guide/firstwidget目录中的6_button.py示例开始 我发现了一些有效的方法(使用pop两次从点中删除最后一个x,y对),但我认为这非常尴尬,请参见下面的代码。我希望有人能告诉我们如何正确地“更新” 基于6_button.py
我也在努力解决同样的问题。我从kivy/guide/firstwidget目录中的6_button.py示例开始 我发现了一些有效的方法(使用pop两次从点中删除最后一个x,y对),但我认为这非常尴尬,请参见下面的代码。我希望有人能告诉我们如何正确地“更新” 基于6_button.py
我用
ipdb
深入研究了代码,我意识到有一个叫做needs\u redraw的Line属性。在当前行中它总是False,并且变量是写保护的。我用ipdb
深入研究代码,我意识到有一个名为needs\u redraw的Line属性。在当前行中它总是False,并且变量是写保护的。这并不是那么尴尬。但是,它没有解释为什么直接分配不起作用self.line.points[2]=touch.x
。我开始认为这是创建新实例的唯一方法,但您找到了另一种方法。我可以告诉您,如果您正在为椭圆
更新pos
,这将失败,因为它是一个元组
,并且没有pop
方法。看看一个Kivy开发者的回答。创建一条新的生产线可能并没有那么错,也并没有那么尴尬。但是,它没有解释为什么直接分配不起作用self.line.points[2]=touch.x
。我开始认为这是创建新实例的唯一方法,但您找到了另一种方法。我可以告诉您,如果您正在为椭圆
更新pos
,这将失败,因为它是一个元组
,并且没有pop
方法。看看一个Kivy开发者的回答。毕竟,创建一条新线可能没有那么错。
from random import random
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.graphics import Color, Ellipse, Line
class MyPaintWidget(Widget):
def on_touch_down(self, touch):
color = (random(), 1, 1)
with self.canvas:
Color(*color, mode='hsv')
d = 10.
Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
touch.ud['line'] = Line(points=(touch.x, touch.y, touch.x+30, touch.y))
#print(dir(touch.ud['line']))
def on_touch_move(self, touch):
#touch.ud['line'].points += [touch.x, touch.y]
touch.ud['line'].points.pop() #
touch.ud['line'].points.pop() # works but is awkward
touch.ud['line'].points += [touch.x, touch.y] #
#touch.ud['line'].points[2:4] = [touch.x, touch.y]
#self.canvas.ask_update() # no error but didnt work
#touch.ud['line'].ask_update() # didnt work
#print(touch.ud['line'].points)
#touch.ud['line'].needs_redraw() # error 'bool not callable'
#touch.ud['line'].needs_redraw = True # error 'not writable'
#touch.ud['line'].needs_redraw #no error but doesnt work
class MyPaintApp(App):
def build(self):
parent = Widget()
painter = MyPaintWidget()
clearbtn = Button(text='Clear')
parent.add_widget(painter)
parent.add_widget(clearbtn)
def clear_canvas(obj):
painter.canvas.clear()
clearbtn.bind(on_release=clear_canvas)
return parent
if __name__ == '__main__':
MyPaintApp().run()