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

如何将Python脚本终端输出显示到Kivy脚本的文本框中

解决Kivy中显示子进程终端输出的问题

问题根源及修复点

  • Lambda变量捕获错误:循环内的lambda会引用同一个line变量,导致UI更新时显示的是最后一行内容。通过给lambda添加默认参数捕获当前line值解决。
  • 弹窗创建顺序问题:原代码先启动线程再创建弹窗,线程中引用output_popup可能触发未定义错误。调整为先创建弹窗再启动线程。
  • 重复关闭输出流:两次调用process.stdout.close(),移除重复调用。
  • 标题栏未挂载:创建的title_bar未加入弹窗内容,导致不显示,需添加到popup_content。
  • 输出缓冲延迟:子进程stdout默认缓冲,设置bufsize=0禁用缓冲,同时在main.py的print语句中添加flush=True确保实时输出。

修正后的boot.py代码

def bootEngram(self, instance):
    try:
        output_textbox = TextInput(
            readonly=True,
            background_color=(0, 0, 0, 1),
            foreground_color="#55ead4",
            font_size=14,
            font_name=fontFile,
            multiline=True
        )

        command = ["python", "D:\\silverhand\\code\\main.py"]
        # 禁用输出缓冲,确保实时捕获输出
        process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=0)

        def update_output_text(instance, line):
            instance.text += line

        def read_output():
            # 读取标准输出,用默认参数捕获当前line值
            for line in iter(process.stdout.readline, ''):
                Clock.schedule_once(lambda dt, l=line: update_output_text(output_textbox, l))
            process.stdout.close()

            # 读取错误输出
            for err in iter(process.stderr.readline, ''):
                Clock.schedule_once(lambda dt, e=err: update_output_text(output_textbox, f"Error: {e}"))
            process.stderr.close()

            process.wait()
            Clock.schedule_once(lambda dt: output_popup.dismiss())

        # 先构建弹窗所有组件
        popup_content = BoxLayout(orientation="vertical", spacing=10)

        title_bar = BoxLayout(orientation="horizontal", size_hint_y=None, height=40, padding=(10, 5))

        title_label = Label(
            text="Engram",
            color="#f3e600",
            font_name=fontFile,
            font_size=20,
            bold=True,
            halign="left",
            size_hint_x=1,
            valign="middle"
        )

        close_button = Button(
            text="<",
            size_hint=(None, None),
            size=(30, 30),
            background_color=(0, 0, 0, 1),
            color=(1, 1, 1, 1),
            bold=True,
            size_hint_x=None
        )

        close_button.bind(on_press=lambda x: output_popup.dismiss())

        title_bar.add_widget(title_label)
        title_bar.add_widget(close_button)

        popup_content.add_widget(title_bar)
        popup_content.add_widget(output_textbox)

        output_popup = Popup(
            title="Engram",
            title_color="#f3e600",
            title_size=20,
            title_font=fontFile,
            size_hint=(0.9, 0.9),
            separator_color="#c5003c",
            auto_dismiss=False,
            content=popup_content
        )

        # 弹窗初始化完成后启动线程
        threading.Thread(target=read_output, daemon=True).start()

        output_popup.open()

    except Exception as e:
        print(f"Error: {e}")

main.py配套修改

将main.py中的打印语句修改为:

print("Hello user!", flush=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 10:09:58