Allow Tabs as input

用户在 Gradio Blocks 中开发需要根据当前选中标签切换输入源的交互逻辑。例如:在“microphone”和“upload”两个标签页中根据用户选择决定使用哪个音频输入。用户尝试将 gr.Tabs 对象直接作为事件输入传入回调函数。

Allow Tabs as input

Allow Tabs as input

快速结论:在 Gradio 的 Blocks 应用中,直接使用 gr.Tabs() 对象作为事件输入参数可能导致程序抛出异常(Tabs 默认不是输入组件)。优先排查方式:改用 Tab.select() 事件将当前标签 ID 存入 gr.State,再读取 State 获取当前选中的标签。

问题场景

用户在 Gradio Blocks 中开发需要根据当前选中标签切换输入源的交互逻辑。例如:在“microphone”和“upload”两个标签页中根据用户选择决定使用哪个音频输入。用户尝试将 gr.Tabs 对象直接作为事件输入传入回调函数。

报错原文

Gradio throws an exception if the Tabs object ends up in an input. (Because it's not an input.)

原因分析

在 Gradio 3.x 版本中,gr.Tabs 不是标准的输入组件,它不具有与 gr.Textboxgr.Number 等组件相同的输入接口。直接将其传入 btn.click(fn, [input1, input2, tabs], output) 会导致 Gradio 抛出异常。但 Issue 确认可以通过 Tab.select() 事件监听到标签切换行为,并能获取到当前标签的 id 属性(前提是在定义标签时主动设置了 id 参数)。

环境排查

  • Gradio 版本:Issue 发生在 3.24.1 及更早版本(提问者使用 3.24.1),但最终确认该设计在后续版本中仍然存在。
  • Python 版本:无明确限制。
  • 其他依赖:无需特殊环境,仅需 Gradio 库。

解决步骤

  1. 方案一(可优先尝试):使用 Tab.select() 事件监听标签切换。
    import gradio as gr
    
    if __name__ == '__main__':
        app = gr.Blocks()
        with app:
            tabs = gr.Tabs()
            with tabs:
                with gr.Tab("microphone") as tab1:
                    input1 = gr.Audio(label="Input Audio", source="microphone")
                with gr.Tab("upload") as tab2:
                    input2 = gr.Audio(label="Input Audio", source="upload")
            btn = gr.Button()
            output = gr.Audio(label="Output Audio")
            # 不直接传入 tabs,而是用 select 事件处理
            tab1.select(lambda: "microphone", None, output)
            tab2.select(lambda: "upload", None, output)
        app.launch()
    
  2. 方案二:结合 gr.State 存储当前选中标签。
    import gradio as gr
    
    def set_tab(tab_id, state):
        state = tab_id
        return state
    
    def process(input1, input2, state):
        if state == "microphone":
            audio = input1
        else:
            audio = input2
        # 处理音频
        return audio
    
    with gr.Blocks() as demo:
        state = gr.State("microphone")
        with gr.Tabs():
            with gr.Tab("microphone", id="microphone") as tab1:
                input1 = gr.Audio(source="microphone")
            with gr.Tab("upload", id="upload") as tab2:
                input2 = gr.Audio(source="upload")
        btn = gr.Button("Process")
        output = gr.Audio()
        tab1.select(set_tab, ["microphone", state], state)
        tab2.select(set_tab, ["upload", state], state)
        btn.click(process, [input1, input2, state], output)
    demo.launch()
    
  3. 方案三:若希望一次性获取选中的标签 ID,可在 gr.Tab 中设置 id 属性,并使用 Tab.select 事件。

验证方法

将原有代码中的 btn.click(fn, [input1, input2, tabs], output) 替换为上述任一方案后,点击按钮应能根据当前选中的标签页正确输出对应的音频结果,不再抛出异常。

参考来源

gradio-app/gradio #3793

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

celebrityanime
celebrityanime
文章: 10711

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注