从根本上应用 kivy 触摸行为:能够感知主屏幕上任何位置的双击、三次点击和长按

Apply kivy touch behaviours at the root: Be able to sense the double, triple tap, and long touch anywhere on the main screen

提问人:She-Codes 提问时间:11/17/2023 更新时间:11/17/2023 访问量:12

问:

在这里,我有一个根(在 kivy 文件中),这是我的应用程序的唯一屏幕。现在,想要检测屏幕上的双重、三重和长触摸。但是,我希望在屏幕上的任何地方都可以检测到它,而不仅仅是通过单击屏幕上列出的一些项目。稍后将更新以使用 pyttsx3,这意味着:如果记录了triple_tap,则作为 allTasks 的一部分读取 (task_being_read) 的任务将从字典 allTasks 中删除。如果捕获了long_touch,则任务的讲授将停止,task_being_read的子任务的讲授将被阅读。最后,如果检测到双击,将停止task_being_read的讲座,并直接进入下一个任务的讲座。

这是主要代码

from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivymd.uix.dialog import MDDialog
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.list import OneLineListItem
from kivymd.uix.button import MDIconButton
import pyttsx3
from kivy.clock import Clock
from kivymd.uix.behaviors import TouchBehavior


class TaskDialogContent(MDBoxLayout):
    def __init__(self, **kwargs):
        super(TaskDialogContent, self).__init__(**kwargs)

class SubTaskDialogContent(MDBoxLayout):
    def __init__(self, task_text="", **kwargs):
        super(SubTaskDialogContent, self).__init__(**kwargs)
        self.ids.subtask_text.text = task_text

class SubTaskShowContent(MDBoxLayout):
    pass


allTasks = {}
currentSelectedTask = ""
class MyApp(MDApp, TouchBehavior):
    engine = pyttsx3.init()
    database_file = 'database2.txt'
    task_list_dialog = None
    subtask_list_dialog = None
    dialog = None

def build(self):
    return Builder.load_file('main2.kv')


def load_tasks_from_file(self):
        file = open("database2.txt", "r")
        lines = file.readlines()
        task = None
        for line in lines:
            line = line.strip()
            if line[0] == "*":
                task = line[1:]
                allTasks[task] = []
            else:
                subtask = line[1:]
                allTasks[task].append(subtask)
        print(allTasks)

    def on_start(self):
        self.load_tasks_from_file()
        self.view_tasks(allTasks)
        Clock.schedule_once(self.second_function, 2)

    def second_function(self, dt):
        self.read_me()



def task_dialog(self):
    if self.task_list_dialog:
        self.task_list_dialog.dismiss()

    self.task_list_dialog = MDDialog(
        title="Create a Task",
        type="custom",
        content_cls=TaskDialogContent()
    )
    self.task_list_dialog.open()



def subtask_dialog(self, key):
    if self.subtask_list_dialog:
        self.subtask_list_dialog.dismiss()

    global currentSelectedTask
    print("current task = ", currentSelectedTask)
    self.subtask_list_dialog = MDDialog(
        title=f"Add a subtask to {key} ",
        type="custom",
        content_cls=SubTaskDialogContent()
    )
    currentSelectedTask = key #-----------This is the one to work with for the touches. I need a new varibale that
    print(currentSelectedTask)
    self.subtask_list_dialog.open()



def add_task(self, taskname):
    allTasks[taskname] = []
    self.view_tasks(allTasks) #just for debugging


def add_subtask(self, subtaskname):
    # subtask_text = self.subtask_list_dialog.content_cls.ids.subtask_text.text
    allTasks[currentSelectedTask].append(subtaskname)
    print("After adding the subtask")
    print(allTasks)

def view_tasks(self, allTasks):
    print(allTasks) #just to view the tasks after adding them
    self.root.ids.container.clear_widgets()
    for key in allTasks:
        item = OneLineListItem(
            MDIconButton(
                icon="tray-plus",
                pos_hint={"center_x": .92, "center_y": 0.5},
                on_release = lambda instance, key = key: app.subtask_dialog(key)
            ),
            MDIconButton(
                icon="trash-can-outline",
                pos_hint={"right": 1, "center_y": 0.5},
                on_release = lambda instance, key = key: app.delete_task(key)
            ),
            text= key,
            on_release = lambda instance, key = key: app.view_subtasks(key)
            )
        self.root.ids.container.add_widget(item)

def view_subtasks(self, key):
    global currentSelectedTask
    currentSelectedTask = key # Here I am changing the value of currentSelectedTask to be teh last task that was selected.
    print("------>The current selected task is " + currentSelectedTask)
    currenttasks = allTasks[key]
    print(currenttasks)
    self.show_subtasks_dialog(currenttasks)

def show_subtasks_dialog(self, subtasks):
    if self.dialog:
        self.dialog.dismiss()

    content = MDBoxLayout(orientation="vertical", adaptive_height=True)

    for subtask in subtasks:
        content.add_widget(OneLineListItem(text=subtask))

    self.dialog = MDDialog(
        title=f"Subtasks for {currentSelectedTask}",
        type="custom",
        content_cls=content,
    )

    self.dialog.open()

def delete_task(self,key):

    widget_to_remove = None
    for widget in self.root.ids.container.children:
        if isinstance(widget, OneLineListItem) and widget.text == key:
            widget_to_remove = widget
            break
    if widget_to_remove:
        self.root.ids.container.remove_widget(widget_to_remove)

    allTasks.pop(key, None)
    print(allTasks)


def close_task_dialog(self, *args):
    self.task_list_dialog.dismiss()

def close_subtask_dialog(self):
    self.subtask_list_dialog.dismiss()

def on_stop(self):
    self.write_to_file()

def write_to_file(self):
    with open("database2.txt", "w") as file:
        for task, subtasks in allTasks.items():
            file.write(f"*{task}\n")
            for subtask in subtasks:
                file.write(f"+{subtask}\n")

def read_me(self):
    self.rate = self.engine.getProperty('rate')
    self.engine.setProperty('rate', 80)
    for key in allTasks:
        task_being_read = key
        print("The task being read is ", task_being_read)
        self.engine.say("Task" + str(key))
        self.engine.runAndWait()


    def on_long_touch(self, *args):
        print("<on_long_touch> event")

    def on_double_tap(self, *args):
        print("<on_double_tap> event")

    def on_triple_tap(self, *args):
        print("<on_triple_tap> event")




if __name__ == "__main__":
    app = MyApp()
    app.run()

这是 kivy 代码

MDFloatLayout:
MDLabel:
    id: task_label
    halign: "center"
    markup: True
    text:"[b][u][size=48]Your Task Manager[/size][/u][/b]"
    pos_hint: {"y": 0.45}

ScrollView:
    pos_hint: {"center_y": 0.5, "center_x": 0.5}
    size_hint: 0.9, 0.8
    MDList:
        id: container

MDFloatingActionButton:
    icon: "plus-thick"
    on_release: app.task_dialog()
    elevation_normal: 12
    pos_hint: {"x": 0.45 , "y": 0.04}


<TaskDialogContent>:
    orientation: "vertical"
    spacing: "10dp"
    size_hint : 1, None
    height: "130dp"

    GridLayout:
        rows: 1

        MDTextField:
            id: task_text
            hint_text: "Add a task ..."
            pos_hint: {"center_y": 0.4}
            max_text_length: 50
            on_text_validate: (app.add_task(task_text.text), app.close_task_dialog())


BoxLayout:
    orientation: "horizontal"

    MDRaisedButton:
        text: "SAVE"
        on_release: (app.add_task(task_text.text), app.close_task_dialog())
    MDFlatButton:
        text: "CANCEL"
        on_release: app.close_task_dialog()


<SubTaskDialogContent>:
    id: subtask_content 
    orientation: "vertical"
    spacing: "10dp"
    size_hint : 1, None
    height: "130dp"

GridLayout:
    rows: 1

    MDTextField:
        id: subtask_text
        hint_text: "Add a subtask ..."
        pos_hint: {"center_y": 0.4}
        max_text_length: 50
        on_text_validate: app.add_subtask(subtask_content.ids.subtask_text.text), app.close_subtask_dialog()


BoxLayout:
    orientation: "horizontal"

    MDRaisedButton:
        text: "SAVE"
        on_release: app.add_subtask(subtask_content.ids.subtask_text.text), app.close_subtask_dialog()
    MDFlatButton:
        text: "CANCEL"
        on_release: app.close_subtask_dialog()


<SubTaskShowContent>:
    orientation: "vertical"

    ScrollView:
        GridLayout:
            id: subtasks_grid
            cols: 1
            spacing: dp(5)
python 移动 kivy kivymd

评论


答: 暂无答案