You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

纯Python实现Kivy可滚动Label时Clock迭代错误解决求助

问题分析与纯Python修复方案

错误根源

  • 无限递归循环:MyLabel的on_size方法中设置self.size = self.texture_size,会导致size属性变更时再次触发on_size事件,形成无限迭代,触发Clock临界错误。
  • 频繁重绘触发:每次通过output_label.text += ...修改文本时,都会立即触发Label的纹理计算和重绘,短时间内大量操作会加重主线程负担。
  • 滚动时机不当:在文本循环中直接设置scroll_y = 0,会在每次添加行时都触发滚动计算,进一步增加主线程压力。

纯Python修复代码

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.clock import Clock
import pyautogui

class MyLabel(Label):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # 绑定texture_size到高度,避免on_size的无限循环
        self.bind(texture_size=self._update_height)

    def _update_height(self, instance, texture_size):
        # 仅更新高度,宽度保持固定
        self.height = texture_size[1]

class MyApp(App):
    def build(self):
        root_widget = BoxLayout(orientation='vertical')
        scroll_label = ScrollView(size_hint_y=None, size=(500, 200), do_scroll_y=True)
        output_label = MyLabel(
            size_hint_y=None, 
            width=500, 
            halign="left", 
            valign="top", 
            color=(0, 0.2, 0, 1),  # Kivy颜色范围为0-1,修正原溢出值
            padding=10
        )
        scroll_label.add_widget(output_label)
            
        def find_image(instance):
            try:
                plus_list = list(pyautogui.locateAllOnScreen('test.png', confidence=0.90, grayscale=False))
                if plus_list:
                    # 批量拼接文本,减少重绘次数
                    new_lines = [f"Result: {tuple(i)}\n" for i in plus_list]
                    output_label.text += ''.join(new_lines)
                else:
                    output_label.text += "No results found\n"
            except Exception as error:
                error_msg = format(error)
                if "Could not locate the image" in error_msg:
                    output_label.text += "Error: Couldn't find the image\n"
                else:
                    output_label.text = "Error: No description\n"
            # 异步调度滚动到底部,避免阻塞主线程
            Clock.schedule_once(lambda dt: setattr(scroll_label, 'scroll_y', 0), 0)

        # 补全原代码省略的控件定义
        button_grid = BoxLayout(size_hint_y=None, height=50)
        paths_grid = BoxLayout(size_hint_y=None, height=50)
        
        root_widget.add_widget(scroll_label)
        root_widget.add_widget(button_grid)
        root_widget.add_widget(paths_grid)

        return root_widget

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

关键修复点说明

  • 解决无限循环:用bind(texture_size=self._update_height)替代on_size方法,仅在纹理尺寸变化时更新Label高度,避免触发size变更的循环事件。
  • 降低重绘频率:批量拼接新文本后一次性更新output_label.text,避免每添加一行就触发一次重绘。
  • 异步滚动处理:使用Clock.schedule_once延迟执行滚动操作,让Kivy在当前帧处理完成后再调整滚动位置,避免主线程阻塞。
  • 修正颜色值:Kivy颜色通道值范围为0-1,原代码中(0,50,0,1)会被自动截断,修正为(0, 0.2, 0, 1)以匹配预期视觉效果。

内容的提问来源于stack exchange,提问作者Jacob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:43:31