Kivy框架中如何实现控件从触摸触发到离开期间持续调用函数
实现方案
步骤1:修改Python逻辑代码
首先导入Kivy的时钟调度模块,新增长按重复执行的控制逻辑,移除原函数内的阻塞sleep:
import kivy from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.clock import Clock # 新增导入时钟模块 import socket kivy.require("1.9.0") client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) class MyRoot(BoxLayout): def __init__(self): self.command = "" self.vol = 0 self.scheduled_task = None # 存储当前正在执行的定时任务 super(MyRoot, self).__init__() # 新增:启动重复执行 def start_repeat(self, func, interval, *args): # 先停止之前可能存在的任务,避免冲突 self.stop_repeat() # 定时每隔interval秒执行一次func self.scheduled_task = Clock.schedule_interval(lambda dt: func(), interval) # 新增:停止重复执行 def stop_repeat(self): if self.scheduled_task is not None: self.scheduled_task.cancel() self.scheduled_task = None def shutdown(self): self.command = "shutdown" self.send_message() def tangAmLuong(self): self.command = "tang_am_luong" self.send_message() if self.vol <= 98: self.vol += 2 self.volume_text.text = str(self.vol) # 移除原来的time.sleep(0.1),用Clock的间隔控制执行频率 def giamAmLuong(self): self.command = "giam_am_luong" self.send_message() if self.vol >= 2: self.vol -= 2 self.volume_text.text = str(self.vol) # 移除原来的time.sleep(0.1) def trai(self): self.command = "sang_trai" self.send_message() def phai(self): self.command = "sang_phai" self.send_message() def len(self): self.command = "len" self.send_message() def xuong(self): self.command = "xuong" self.send_message() def chuot_trai(self): self.command = "chuot_trai" self.send_message() def chuot_phai(self): self.command = "chuot_phai" self.send_message() def send_message(self): client.send(f"{self.nickname_text.text}: {self.command}".encode("utf-8")) def connect_to_server(self): if self.nickname_text != "": client.connect((self.ip_text.text, 9999)) self.send_message() class style(App): def build(self): return MyRoot() webChat = style() webChat.run()
步骤2:修改KV布局文件
给需要长按持续触发的按钮新增on_release事件,修改on_press事件绑定启动重复执行的逻辑,按需设置执行间隔(示例里设为0.1秒,可自行调整):
ip_text: ip_text nickname_text: nickname_text connect_btn: connect_btn connection_grid: connection_grid shutdown_btn: shutdown_btn tangal_btn: tangal_btn giamal_btn: giamal_btn volume_text: volume_text orientation: 'vertical' GridLayout: id: connection_grid rows: 1 cols: 2 padding: 10 spacing: 10 height: 125 size_hint: (1, None) BoxLayout: orientation: 'vertical' Label: text: "Server IP" font_size: 42 color: 0.92, 0.45, 0, 1 TextInput: id: ip_text size_hint: (1, None) height: 50 font_size: 36 BoxLayout: orientation: 'vertical' Label: text: "Nickname" font_size: 42 color: 0.92, 0.45, 0, 1 TextInput: id: nickname_text size_hint: (1, None) height: 50 font_size: 36 Button: id: connect_btn text: "Connect" font_size: 32 size: 100, 50 size_hint: (1, None) height: 50 on_press: root.connect_to_server() Button: id: shutdown_btn text: "Tắt máy" font_size: 32 size: 100, 50 size_hint: (1, None) height: 50 on_press: root.shutdown() Button: id: tangal_btn text: "Tăng âm lương" font_size: 32 size: 100, 50 size_hint: (1, None) height: 50 on_press: root.start_repeat(root.tangAmLuong, 0.1) on_release: root.stop_repeat() Button: id: giamal_btn text: "Giảm âm lượng" font_size: 32 size: 100, 50 size_hint: (1, None) height: 50 on_press: root.start_repeat(root.giamAmLuong, 0.1) on_release: root.stop_repeat() Label: id: volume_text text: "0" font_size: 36 GridLayout: rows: 3 cols: 3 Button: text: "Chuột Trái" font_size: 14 on_press: root.chuot_trai() Button: text: "Lên" font_size: 14 on_press: root.start_repeat(root.len, 0.05) # 鼠标移动可以设置更短的间隔更跟手 on_release: root.stop_repeat() Button: text: "Chuột Phải" font_size: 14 on_press: root.chuot_phai() Button: text: "Trái" font_size: 14 on_press: root.start_repeat(root.trai, 0.05) on_release: root.stop_repeat() Label: text: "" font_size: 14 Button: text: "Phải" font_size: 14 on_press: root.start_repeat(root.phai, 0.05) on_release: root.stop_repeat() Label: text: "" font_size: 14 Button: text: "Xuống" font_size: 14 on_press: root.start_repeat(root.xuong, 0.05) on_release: root.stop_repeat() Label: text: "" font_size: 14
注意事项
- 执行间隔可根据需求调整,数值越小触发频率越高
- 不要在被调度的功能函数里加
time.sleep(),会阻塞Kivy主线程导致界面卡顿 - 如果需要支持多点触摸同时触发多个按钮,可以把
self.scheduled_task改成字典,按按钮ID存储不同的调度任务即可
内容的提问来源于stack exchange,提问作者Hùng Nguyễn
相关产品推荐
相关产品推荐

