全面解析 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>""")# 右侧按钮:获取手机 Appwith 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前端进行通信的接口。以搭建一个有用户登录、注册界面,对话界面、会话历史等界面的问答系统。希望我的学习过程对宝子们有帮助,预祝各位都能实现编程自由。