kivy collide_point行为与预期不符

时间:2017-12-03 16:38:08

标签: python kivy

我想创建一个应用程序,其中三列标签并排显示。每列应包含在BoxLayout中。上下滚动鼠标滚轮,根据光标是位于左侧还是右侧BoxLayout,应触发不同的事件,并相应更改左侧或右侧列的标签。

这是我创建的代码:

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout

matrix = [500, 500, 500, 5, 5]

class LoginScreen(BoxLayout):

    def __init__(self, **kwargs):
        super(LoginScreen, self).__init__(**kwargs)
        self.orientation = 'horizontal'

        self.container_L = MyLayout_L(orientation = 'vertical', on_touch_down = self.change_label_L)
        self.container_M = BoxLayout(orientation = 'vertical')
        self.container_R = MyLayout_R(orientation = 'vertical', on_touch_down = self.change_label_R)

        self.label_L0 = Label(text = '3', font_size = 30)
        self.label_L1 = Label(text = '4', font_size = 30)
        self.label_L2 = Label(text = '5', font_size = 30)
        self.label_L3 = Label(text = '6', font_size = 30)
        self.label_L4 = Label(text = '7', font_size = 30)

        label_L_list = [self.label_L0, self.label_L1, self.label_L2, self.label_L3, self.label_L4]
        for item in label_L_list:
            self.container_L.add_widget(item)

        self.label_M0 = Label(text = '500', font_size = 30)
        label_M_list = [self.label_M0]
        for item in label_M_list:
            self.container_M.add_widget(item)

        self.label_R0 = Label(text = '3', font_size = 30)
        self.label_R1 = Label(text = '4', font_size = 30)
        self.label_R2 = Label(text = '5', font_size = 30)
        self.label_R3 = Label(text = '6', font_size = 30)
        self.label_R4 = Label(text = '7', font_size = 30)

        label_R_list = [self.label_R0, self.label_R1, self.label_R2, self.label_R3, self.label_R4]
        for item in label_R_list:
            self.container_R.add_widget(item)

        self.add_widget(self.container_L)
        self.add_widget(self.container_M)
        self.add_widget(self.container_R)

    def change_label_L(self, instance, Label):
        print 'L ', matrix
        counter = matrix[3]
        self.label_L0.text = str(counter-2)
        self.label_L1.text = str(counter-1)
        self.label_L2.text = str(counter)
        self.label_L3.text = str(counter+1)
        self.label_L4.text = str(counter+2)

    def change_label_R(self, instance, BoxLayout):
        print 'R ', matrix
        counter = matrix[4]
        self.label_R0.text = str(counter-2)
        self.label_R1.text = str(counter-1)
        self.label_R2.text = str(counter)
        self.label_R3.text = str(counter+1)
        self.label_R4.text = str(counter+2)

class MyLayout_L(BoxLayout):
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            if touch.button == 'scrollup':
                self.calc_plus()
            elif touch.button == 'scrolldown':
                self.calc_minus()
    def calc_plus(self):
        matrix[3] += 1
    def calc_minus(self):
        matrix[3] -= 1

class MyLayout_R(BoxLayout):
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            if touch.button == 'scrollup':
                self.calc_plus2()
            elif touch.button == 'scrolldown':
                self.calc_minus2()
    def calc_plus2(self):
        matrix[4] += 1
    def calc_minus2(self):
        matrix[4] -= 1

class MyApp(App):
    def build(self):
        return LoginScreen()

if __name__ == '__main__':
    MyApp().run()

现在,问题是代码有一些奇怪的行为。已创建类MyLayout_RMyLayout_L以识别鼠标光标是否位于右侧BoxLayout的左侧,并使on_touch_down事件触发{{1} }或change_label_R函数。

然而,在终端中我看到两个函数同时被触发(请参阅代码中的change_label_Lprint 'L ', matrix行,这些行都是在滚动时执行的。)

此外,BoxLayouts中的标签正在发生变化,但并不完全符合计划。

  • 当我更改光标的位置时,左侧BoxLayout标签 将始终跳过一步(比较终端输出和标签)。

  • 此外,更改位置时,将触发第一次滚动 旧的Boxlayout和下一个滚动将触发现在 之一。

由于print 'R ', matrix检查光标是否位于手头小部件的区域内,为什么滚动会影响BoxLayouts?我想我错过了一些重要的东西,因此任何帮助都会受到赞赏。

2 个答案:

答案 0 :(得分:0)

您的collide_point()工作正常。问题是您已设置两个方法来处理每个类的on_touch_down个事件。您在self.container_L = MyLayout_L(orientation = 'vertical', on_touch_down = self.change_label_L)中创建的内容以及“R”类似的内容不使用collide_point(),因此它们会在每个事件上执行。

答案 1 :(得分:0)

这是您的代码,编辑为每个MyLayout类只有一个on_touch_down()方法。

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout

matrix = [500, 500, 500, 5, 5]

class LoginScreen(BoxLayout):

    def __init__(self, **kwargs):
        super(LoginScreen, self).__init__(**kwargs)
        self.orientation = 'horizontal'

        self.container_L = MyLayout_L(orientation = 'vertical', on_touch_down = self.change_label_L)
        self.container_M = BoxLayout(orientation = 'vertical')
        self.container_R = MyLayout_R(orientation = 'vertical', on_touch_down = self.change_label_R)

        self.label_L0 = Label(text = '3', font_size = 30)
        self.label_L1 = Label(text = '4', font_size = 30)
        self.label_L2 = Label(text = '5', font_size = 30)
        self.label_L3 = Label(text = '6', font_size = 30)
        self.label_L4 = Label(text = '7', font_size = 30)

        label_L_list = [self.label_L0, self.label_L1, self.label_L2, self.label_L3, self.label_L4]
        for item in label_L_list:
            self.container_L.add_widget(item)

        self.label_M0 = Label(text = '500', font_size = 30)
        label_M_list = [self.label_M0]
        for item in label_M_list:
            self.container_M.add_widget(item)

        self.label_R0 = Label(text = '3', font_size = 30)
        self.label_R1 = Label(text = '4', font_size = 30)
        self.label_R2 = Label(text = '5', font_size = 30)
        self.label_R3 = Label(text = '6', font_size = 30)
        self.label_R4 = Label(text = '7', font_size = 30)

        label_R_list = [self.label_R0, self.label_R1, self.label_R2, self.label_R3, self.label_R4]
        for item in label_R_list:
            self.container_R.add_widget(item)

        self.add_widget(self.container_L)
        self.add_widget(self.container_M)
        self.add_widget(self.container_R)

    def change_label_L(self, instance, touch):
        if instance.collide_point(*touch.pos):
            print 'L ', matrix
            counter = matrix[3]
            self.label_L0.text = str(counter-2)
            self.label_L1.text = str(counter-1)
            self.label_L2.text = str(counter)
            self.label_L3.text = str(counter+1)
            self.label_L4.text = str(counter+2)
            if touch.button == 'scrollup':
                instance.calc_plus()
            elif touch.button == 'scrolldown':
                instance.calc_minus()


    def change_label_R(self, instance, touch):
        if instance.collide_point(*touch.pos):
            print 'R ', matrix
            counter = matrix[4]
            self.label_R0.text = str(counter-2)
            self.label_R1.text = str(counter-1)
            self.label_R2.text = str(counter)
            self.label_R3.text = str(counter+1)
            self.label_R4.text = str(counter+2)
            if touch.button == 'scrollup':
                instance.calc_plus2()
            elif touch.button == 'scrolldown':
                instance.calc_minus2()

class MyLayout_L(BoxLayout):
    def calc_plus(self):
        matrix[3] += 1
    def calc_minus(self):
        matrix[3] -= 1

class MyLayout_R(BoxLayout):
    def calc_plus2(self):
        matrix[4] += 1
    def calc_minus2(self):
        matrix[4] -= 1

class MyApp(App):
    def build(self):
        return LoginScreen()

if __name__ == '__main__':
    MyApp().run()