【Gradio解析】深入探索Gradio Blocks框架:构建敏捷Python前端界面

全面解析 Gradio 的 Blocks 框架:构建灵活的 Python 前端界面

  • 1. Blocks 框架的作用
  • 核心概念与组件
  • 2.快速上手:构建一个简单的 Blocks 界面
  • 3. 组合 Row 和 Column创建复杂布局
  • 4. 实战案例:使用 Gradio Blocks 框架构建类似 DeepSeek 的首页界面
  • 1. Blocks 框架的作用

    Blocks 框架是 Gradio 的核心功能之一,提供了更高的灵活性和控制能力。与传统的 gr.Interface 不同,Blocks 允许开发者:

  • 自定义界面布局。
  • 定义复杂的交互逻辑。
  • 组合多个输入和输出组件。
  • 创建多页面或多步骤的应用。
  • 核心概念与组件

    在 Blocks 框架中,有几个关键的概念需要了解:
    Blocks 和 Components

  • Blocks 是 Gradio 界面的基本容器,用于组织和管理组件。
  • Components 是界面中的具体元素,例如 gr.Textbox、gr.Image、gr.Slider 等。
  • Layouts(布局)
    Blocks 支持多种布局方式,包括:

  • Row(行) :水平排列组件。
  • Column(列) :垂直排列组件。
  • Tabs(标签页) :分组显示不同的界面部分。
  • Events(事件)
    通过 fn 参数绑定函数,可以实现组件间的交互逻辑。例如,当用户点击按钮时触发某个函数。例如:

        greet_button.click(
            fn=greet, 
            inputs=name_input,
            outputs=output_text
        )
    

    2.快速上手:构建一个简单的 Blocks 界面

    当点击按钮greet_button时,按钮绑定了fn= greet事件,inputs作为事件的输入,outputs作为事件的输出。

    import gradio as gr
    
    # 定义一个处理函数
    def greet(name):
        return f"Hello, {name}!"
    
    # 使用 Blocks 构建界面
    with gr.Blocks() as demo:
        # 添加标题
        gr.Markdown("# Welcome to the Greeting App")
        # 添加输入组件
        name_input = gr.Textbox(label="Enter your name")
        # 添加输出组件
        output_text = gr.Textbox(label="Greeting Message")
        # 添加按钮并绑定事件
        greet_button = gr.Button("Greet")
        greet_button.click(
            fn=greet, 
            inputs=name_input,
            outputs=output_text
        )
    # 启动应用
    demo.launch()
    

    3. 组合 Row 和 Column创建复杂布局

    当我们熟练掌握了Row 和 Column后,在设计界面的时候就可以随心所欲的设计了,掌握嵌套使用,设计更加完美的布局。以下是展示嵌套使用并且添加相关的组件。每一个都可以调整显示的效果:
    Row():
    参数:

  • variant: row type , ‘default’(无背景)、‘panel’(灰色背景和圆角)or ‘compact’(圆角和无内部间隙)。
  • visible:如果为False,则行将被隐藏。
  • elem_id:一个可选字符串,在HTML DOM中指定为此组件的id。可用于定位CSS样式。
  • elem_classes:一个可选的字符串或字符串列表,在HTML DOM中被指定为该组件的类。可用于定位CSS样式。
  • render:如果为False,则此布局将不会在“块”上下文中呈现。如果目的是现在分配事件侦听器,但稍后呈现组件,则应使用。
  • equal_height:如果为True,则使每个子元素具有相等的高度
  • show_progress:如果为True,则在更新时显示进度动画。
  • gr.Column():
    参数:

  • scale:与相邻列相比的相对宽度。例如,如果列A的scale=2,列B的scale=1,则A的宽度将是B的两倍。
  • min_width:列的最小像素宽度,如果没有足够的屏幕空间来满足此值,将自动换行。如果某个比例值导致列的宽度小于min_width,则min_widch参数将首先被考虑。
  • variant:列类型、“默认”(无背景)、“面板”(灰色背景和圆角)或“紧凑”(圆角和无内部间隙)。
  • visible:如果为False,则列将隐藏。
  • elem_id:一个可选字符串,在HTML DOM中指定为此组件的id。可用于定位CSS样式。
  • elem_classes:一个可选的字符串或字符串列表,在HTML DOM中被指定为该组件的类。可用于定位CSS样式。
  • render:如果为False,则组件将不会在“块”上下文中渲染。如果目的是现在分配事件侦听器,但稍后呈现组件,则应使用。
  • show_progress:如果为True,则在更新时显示进度动画。
  • 当然,gr.Markdown、 gr.Button、gr.Textbox 也都有自己相应的参数,在编译器里面 使用 "CTRL+ 鼠标左键"查看相关参数,这里就不过多总结了。

    import gradio as gr
    
    # 主界面
    with gr.Blocks() as demo:
        # 自定义 CSS 样式:为 Row 和 Column 添加边框
        demo.css = """
        .highlight-border {
            border: 2px solid #007BFF; /* 蓝色边框 */
            padding: 10px;             /* 内边距 */
            margin: 5px;               /* 外边距 */
            border-radius: 5px;        /* 圆角 */
        }
        """
    
        # 顶部导航栏(使用 Row)
        with gr.Row(elem_classes="highlight-border"):
            gr.Markdown("### 顶部导航栏")
            with gr.Column(elem_classes="highlight-border"):
                gr.Button("按钮 1")
                gr.Button("按钮 2")
    
            # 中间内容区域(使用 Column 嵌套 Row)
            with gr.Column(elem_classes="highlight-border"):
                gr.Markdown("#### 左侧内容")
                with gr.Row(elem_classes="highlight-border"):
                    gr.Textbox(label="输入框 1")
                    gr.Textbox(label="输入框 2")
    
                gr.Markdown("#### 右侧内容")
                with gr.Row(elem_classes="highlight-border"):
                    gr.Checkbox(label="选项 1")
                    gr.Checkbox(label="选项 2")
    
        # 底部工具栏(使用 Row)
        with gr.Row(elem_classes="highlight-border"):
            gr.Markdown("### 底部工具栏")
            gr.Button("提交")
            gr.Button("重置")
    
    # 启动应用
    demo.launch()
    

    4. 实战案例:使用 Gradio Blocks 框架构建类似 DeepSeek 的首页界面

    我们从deepseek的主界面可以看到,总共分为以下部分:

  • 顶部导航栏 :显示品牌 Logo、API 开放平台链接和语言切换选项。
  • 公告横幅 :展示重要通知(例如“DeepSeek-R1 已发布并开源”)。
  • 品牌标识 :突出显示品牌名称和标语。
  • 主要内容区域 :包含两个主要按钮:
  • “开始对话”:引导用户与模型进行对话。
  • “获取手机 App”:提供下载官方 App 的链接。
  • 1. 顶部导航栏 (top_navigation)
    关键属性说明:
    elem_id:元素唯一标识符,用于 CSS/JavaScript 操作
    elem_classes:应用预定义的 CSS 类(需在 CSS 中定义 .no-border)
    show_label=False:隐藏组件的默认标题标签
    width/height:控制显示尺寸(不影响原图比例)

    2. 公告横幅 (announcement_banner)
    关键属性说明:
    rgba(255,255,255,0.8):白色背景带 80% 透明度
    margin: 60px:距离上下左右各 60px 的外边距
    border-radius: 5px:圆角边框
    text-align: center:文字居中
    3. 品牌标识 (brand_identification)
    关键属性说明:
    color: #007BFF:品牌蓝色主色调
    text-align: center:强制居中布局
    4. 主内容区域 (main_content_area)
    关键属性说明:
    equal_height=True:强制子列等高
    variant:使用主题预设样式(需在 CSS 中定义 primary/secondary 类)
    5. 全局样式 (demo.css)
    rgba() 实现背景透明度控制
    6. 应用启动
    默认启动在 localhost:7860

    代码:

    import gradio as gr
    
    # 定义顶部导航栏
    def top_navigation():
        with gr.Row():  # 创建横向布局容器
            gr.Image(
                value="image/1.jpg",   # 图片路径(注意路径层级)
                label=None,            # 隐藏默认标签
                elem_id="logo",        # DOM元素ID(用于CSS/JS定位)
                show_label=False,      # 强制不显示标签
                width=100,            # 显示宽度(像素)
                height=100,           # 显示高度(像素)
                elem_classes=["no-border"]  # 自定义CSS类名
            )
    
            # 中间空隙
            gr.Markdown(" ")
            gr.Markdown(" ")
            gr.Markdown(" ")
    
            # 右侧 API 开放平台和语言切换
            with gr.Column():
                gr.Markdown(
                    """ 
                    <div style="display: flex; justify-content: space-between; align-items: center;">
                        <a href="https://api.openplatform.com" target="_blank" style="text-decoration: none; color: #007BFF;">API 开放平台</a>
                        <span>English</span>
                    </div>
                    """, # HTML内联样式
                    elem_id="top-right-links" # DOM元素ID
                )
    
    # 定义公告横幅
    def announcement_banner():
        gr.Markdown(
            """
            <div style="background-color: rgba(255, 255, 255, 0.8); padding: 20px; margin: 60px; border-radius: 5px; text-align: center;">
                🎉 DeepSeek-R1 已发布并开源,性能对标 OpenAI o1 正式版,在网页端、APP 和 API 全面上线,点击查看详情。
            </div>
            """,
            elem_id="announcement-banner" # 绑定CSS选择器
        )
    
    # 定义品牌标识
    def brand_identification():
        with gr.Column(elem_id="brand-section"): # 带ID的纵向容器
            gr.Markdown(
                """
                <h1 style="font-size: 60px; color: #007BFF; text-align: center;">deepseek</h1>
                <p style="font-size: 24px; color: #333; text-align: center;">探索未至之境</p>
                """
            )
    
    # 定义主要内容区域
    def main_content_area():
        with gr.Row(elem_id="main-content", equal_height=True): # 等高的横向容器
            # 左侧按钮:开始对话
            with gr.Column(elem_id="start-conversation-box", variant="primary"): # 主样式变体
                gr.Markdown(
                    """
                    <h3 style="font-size: 24px; color: #007BFF; text-align: center;">开始对话</h3>
                    <p style="font-size: 16px; color: #666; text-align: center;">与 DeepSeek-V3 和 R1 免费对话<br>体验全新旗舰模型</p>
                    """
                )
    
            # 右侧按钮:获取手机 App
            with gr.Column(elem_id="get-app-box", variant="secondary"): # 次样式变体
                gr.Markdown(
                    """
                    <h3 style="font-size: 24px; color: #007BFF; text-align: center;">获取手机 App</h3>
                    <p style="font-size: 16px; color: #666; text-align: center;">DeepSeek 官方推出的免费 AI 助手<br>搜索写作阅读解题翻译工具</p>
                    """
                )
    
    # 主界面
    with gr.Blocks() as demo:
        # 设置背景样式
        demo.css = """
        #brand-section {   /* ID选择器 */
            text-align: center;
            margin-top: 50px;  /* 顶部外边距 */
        }
        #main-content > div {  /* 子元素选择器 */
            padding: 20px;
            border: 2px solid #007BFF;  /* 蓝色边框 */
            border-radius: 10px; /* 圆角 */
            transition: all 0.3s ease;  /* 过渡动画 */
            background-color: rgba(255, 255, 255, 0.9); /* 半透明背景 */
        }
        #main-content > div:hover {
            transform: scale(1.05);  /* 悬停放大效果 */
        }
        """
    
        # 顶部导航栏
        top_navigation()
        # 公告横幅
        announcement_banner()
        # 品牌标识
        brand_identification()
        # 主内容区域
        main_content_area()
    
    # 启动应用
    demo.launch()
    

    结果显示:

    Gradio 的 Blocks 框架为开发者提供了一种强大而灵活的方式来构建交互式界面。无论是简单的单页应用还是复杂的多步骤表单,Blocks 都能胜任。如果你正在寻找一种快速构建前端界面的方法,不妨试试 Gradio 的 Blocks 框架!接下来的笔记将学习如何开发一个类似于deepseek的问答系统,用gradio实现前端界面。后续会更新llm过程代码以及通过FastAPI与gradio前端进行通信的接口。以搭建一个有用户登录、注册界面,对话界面、会话历史等界面的问答系统。希望我的学习过程对宝子们有帮助,预祝各位都能实现编程自由。

    作者:猿来&如此

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【Gradio解析】深入探索Gradio Blocks框架:构建敏捷Python前端界面

    发表回复