如何在Kivy中更新小部件的on_touch_move和on_touch_down方法

时间:2020-10-23 18:37:49

标签: python canvas kivy bind

我目前正在创建绘画应用程序,并且为此使用了Widget画布。 基本上,我已经定义了创建直线和curve_line的方法。但是问题是我无法在这两种方法之间切换。意味着我有两个按钮来触发这些方法,每个方法都将小部件与on_touch_downon_touch_move方法绑定。我的问题是应用程序开始运行后第一次出现问题,例如,我单击名称为f hand的按钮即可正常工作,然后单击了下一个按钮后,小部件将这两种方法自身绑定在一起,从而造成混乱。现在,我希望小部件一次只能用一种方法来绑定自己..我怎么能实现这一目标。

我的python代码在这里

import kivy
from kivy.uix.widget import Widget
from kivy.uix.widget import Canvas
from kivy.graphics import Color
from kivy.graphics import Line
from kivy.uix.floatlayout import FloatLayout
from kivy.app import App
from kivy.uix.button import Button

class Main(FloatLayout):


    def __init__(self,**kwargs):
        super(Main, self).__init__(**kwargs)

        self.my_widget = Widget(size_hint= (0.6,0.6),pos_hint = {'x':0.5,'top' : 0.8})
        self.add_widget(self.my_widget)

        self.free_hand = Button(text='f_hand',pos_hint = {'x':0.04,'top':0.2},size_hint = (0.12,0.12))
        self.add_widget(self.free_hand)
        self.free_hand.bind(on_press = self._free_hand)

        self._hand = Button(text='s_hand', pos_hint={'x': 0.04, 'top': 0.6}, size_hint=(0.12, 0.12))
        self.add_widget(self._hand)
        self._hand.bind(on_press=self._straight_lines)


    def _free_hand(self,instance):


        def on_touch_downah(self,touch):
            self.line = Line(points = (touch.x,touch.y),width = 5)
            self.canvas.add(self.line)
            '''self.line_list.append(self.line)
            print(self.line_list)'''
        
        def on_touch_moveah(self,touch):
            self.line.points += touch.x,touch.y

        self.my_widget.bind(on_touch_down=on_touch_downah)
        self.my_widget.bind(on_touch_move=on_touch_moveah)

    def _straight_lines(self,instance):

        def on_touch_downeh(self, touch):
            self.x_ = touch.x
            self.y_ = touch.y
            self.lines = Line(points=(touch.x,touch.y),width = 5)
            self.canvas.add(self.lines)

        def on_touch_moveeh(self, touch):
            self.x2 = self.x_ + 0.1
            self.y2 = self.y_ + 0.1
            self.lines.points = (self.x_,self.y_,self.x2,self.y2,touch.x,touch.y)

        self.my_widget.bind(on_touch_down=on_touch_downeh)
        self.my_widget.bind(on_touch_move=on_touch_moveeh)


'''
    def undo_1(self):
        self.i -= 1
        k = self.line_list[self.i]
        self.canvas.remove(k)
'''

class Myapp(App):
    def build(self):
        return Main()

Myapp().run()

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

根据@inclement的建议,以下是代码的修改版本,其中仅两个方法绑定到on_touch_downon_touch_move。由Buttons触发的方法只需为图形设置mode,绑定的方法将根据当前模式选择要执行的操作:

from kivy.uix.widget import Widget
from kivy.graphics import Line
from kivy.uix.floatlayout import FloatLayout
from kivy.app import App
from kivy.uix.button import Button

class Main(FloatLayout):


    def __init__(self,**kwargs):
        super(Main, self).__init__(**kwargs)

        self.my_widget = Widget(size_hint= (0.6,0.6),pos_hint = {'x':0.5,'top' : 0.8})
        self.add_widget(self.my_widget)

        self.free_hand = Button(text='f_hand',pos_hint = {'x':0.04,'top':0.2},size_hint = (0.12,0.12))
        self.add_widget(self.free_hand)
        self.free_hand.bind(on_press = self._free_hand)

        self._hand = Button(text='s_hand', pos_hint={'x': 0.04, 'top': 0.6}, size_hint=(0.12, 0.12))
        self.add_widget(self._hand)
        self._hand.bind(on_press=self._straight_lines)

        self.mode = None  # could be "free_hand" or "straight_lines"
        self.my_widget.bind(on_touch_down=self.on_touch_downh)
        self.my_widget.bind(on_touch_move=self.on_touch_moveh)


    def _free_hand(self,instance):
        self.mode = "free_hand"

    def _straight_lines(self,instance):
        self.mode = "straight_lines"

    def on_touch_downh(self, widget, touch):
        if self.mode == "free_hand":
            self.free_hand_touch(touch)
        elif self.mode == "straight_lines":
            self.straight_lines_touch(touch)

    def on_touch_moveh(self, widget, touch):
        if self.mode == "free_hand":
            self.free_hand_move(touch)
        elif self.mode == "straight_lines":
            self.straight_lines_move(touch)

    def free_hand_touch(self,touch):
        self.line = Line(points = (touch.x,touch.y),width = 5)
        self.canvas.add(self.line)
        '''self.line_list.append(self.line)
        print(self.line_list)'''

    def free_hand_move(self,touch):
        self.line.points += touch.x,touch.y

    def straight_lines_touch(self, touch):
        self.x_ = touch.x
        self.y_ = touch.y
        self.lines = Line(points=(touch.x,touch.y),width = 5)
        self.canvas.add(self.lines)

    def straight_lines_move(self, touch):
        self.x2 = self.x_ + 0.1
        self.y2 = self.y_ + 0.1
        self.lines.points = (self.x_,self.y_,self.x2,self.y2,touch.x,touch.y)

'''
    def undo_1(self):
        self.i -= 1
        k = self.line_list[self.i]
        self.canvas.remove(k)
'''

class Myapp(App):
    def build(self):
        return Main()

Myapp().run()

请注意,在您的原始代码中,每次按下一个按钮时,您将绑定更多方法。

相关问题