如何使 on_touch_down 小部件具体化?

Posted

技术标签:

【中文标题】如何使 on_touch_down 小部件具体化?【英文标题】:How do I make on_touch_down widget specific? 【发布时间】:2018-05-19 15:50:55 【问题描述】:

我正在尝试在 kivy 中创建一个简单的绘图应用程序,但我遇到了一些问题

on_touch_down

函数涉及整个类,而不仅仅是特定的小部件。因此,当我使用 on touch down 和 on touch move 功能在画布上绘图时,它会影响并有效地禁用绑定到按钮的 touch down 功能。这是按钮不起作用的代码。

python 代码:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.graphics import Line
from kivy.graphics import *
from kivy.uix.widget import Widget
class MyScreenManager(ScreenManager):
    pass

class MenuScreen(Screen):
    pass

class DrawScreen(Screen):
    def on_touch_down(self, touch):
        with self.canvas.before:
            Color(1, 0, 0)
            touch.ud["line"] = Line(points=(touch.x, touch.y), width=5)

    def on_touch_move(self, touch):
        touch.ud["line"].points += (touch.x, touch.y)



class DrawApp(App):
    def build(self):
        return MyScreenManager()

DrawApp().run()

kivy 代码:

<MenuButton@Button>:
    font_size: 65
    size_hint: 0.4, 0.25

<MyScreenManager>:
    MenuScreen:
        id: menu
        name: "menu"

    DrawScreen:
        id: draw
        name: "draw"

<MenuScreen>:
    canvas.before:
        Color:
            rgba: 1,1,1,1
        Rectangle:
            size: self.size
            pos: self.pos

    MenuButton:
        text: "Draw"
        on_release: root.manager.current = "draw"
        pos_hint:"center_x":0.5, "center_y":0.6
    MenuButton:
        text: "Quit"
        on_release: app.stop()
        pos_hint:"center_x":0.5, "center_y":0.3

<DrawScreen>:
    canvas.before:
        Color:
            rgba: 1,1,1,1
        Rectangle:
            size: self.size
            pos: self.pos


    Button:
        id: but
        size_hint: 0.2,0.1
        pos_hint_x: 0 + self.width
        font_size: 30
        text: "Back"
        on_release: root.manager.current = "menu"

我设法通过使用 collide_point 找到了一个简单的解决方法,这是我的解决方法代码:

class DrawScreen(Screen):
    def on_touch_down(self, touch):
        but = self.ids.but
        if but.collide_point(touch.x, touch.y):
            self.manager.current = "menu"

        else:
            with self.canvas.before:
                Color(1, 0, 0)
                touch.ud["line"] = Line(points=(touch.x, touch.y), width=5)

    def on_touch_move(self, touch):
        touch.ud["line"].points += (touch.x, touch.y)

但是,虽然这有效,但它带来了一个全新的问题,例如我必须手动配置每个按钮以在按住时更改源,并且在释放按钮之前该功能不会运行。这也意味着我添加到类中的所有内容都必须添加到 if 语句中。

我非常肯定必须有一个更简单的方法。我的第一个想法是,也许可以添加 on touch down 以仅影响一个小部件?我的第二个想法是,也许最好不要在画布上画画什么的?

感谢任何帮助或指点,谢谢!

【问题讨论】:

【参考方案1】:

当你覆盖一个方法时,你必须返回超类的相同方法

类似这样的:

...

class DrawScreen(Screen):
    def on_touch_down(self, touch):
        with self.canvas.before:
            Color(1, 0, 0)
            touch.ud["line"] = Line(points=(touch.x, touch.y), width=5)
        return super(DrawScreen, self).on_touch_down(touch)

    def on_touch_move(self, touch):
        touch.ud["line"].points += (touch.x, touch.y)
        return super(DrawScreen, self).on_touch_move(touch)

【讨论】:

以上是关于如何使 on_touch_down 小部件具体化?的主要内容,如果未能解决你的问题,请参考以下文章

如何使两个小部件高度相同?

如何删除小部件之间的线条并使其他小部件居中?

布局:如何在垂直布局中使一个小部件成为其余小部件的 3 倍

如何使 Gridstack.js 小部件垂直响应?

如何使小部件在颤动中相互浮动[关闭]

如何使布局填充qt选项卡小部件内的所有内容?