
Gradio Blocks 布局控制完全指南Row、Column、Tab 与可见性动态布局实战【免费下载链接】gradioBuild and share delightful machine learning apps, all in Python. Star to support our work!项目地址: https://gitcode.com/GitHub_Trending/gr/gradioGradio 的BlocksAPI 默认把所有组件按垂直方向堆叠但在构建真实机器学习演示表单、多任务工具、向导式流程时几乎都需要自定义排列方式。本指南以仓库中 控制布局指南中文 为主线系统讲解gr.Row、gr.Column、gr.Tab、gr.Accordion、可见性切换与组件延迟渲染等全部布局手段并结合 gradio/layouts 下的源码实现与 demo 目录中的可运行示例帮助读者彻底掌握 Blocks 界面的布局控制能力能独立编排从简单并排按钮到可变数量输出分步向导的任意界面。提示本仓库中同一篇指南还有英文完整版本 guides/03_building-with-blocks/02_controlling-layout.md含部分较新的布局特性如浏览器全高全宽、Walkthrough 分步向导正文中已合并说明。布局的底层模型flexbox在gr.Blocks()中组件默认按垂直方向依次排列。若要重新排列组件核心思路是把界面切分为行Row与列Column两类容器并将组件放入其中。这一套布局在浏览器底层使用的是 Web 开发标准中的flexbox 弹性盒模型。因此scale、min_width这些概念本质上都映射为 flexbox 的伸缩与换行规则——理解 flexbox 有助于预测不同屏幕宽度下的表现。本文所有布局类Row、Column、Tabs、Accordion、Sidebar 等均继承自BlockContext集中定义在 gradio/layouts 目录中可直接阅读源码核对每个参数。Row让组件水平并排基础用法将组件放进with gr.Row:代码块内它们就会横向排列。例如并排显示两个按钮import gradio as gr with gr.Blocks() as demo: with gr.Row(): btn1 gr.Button(按钮1) btn2 gr.Button(按钮2)等高排列equal_height默认情况下同一行内的组件各自按内容决定高度。若希望行内所有元素高度一致可在创建 Row 时传入equal_heightTrueimport gradio as gr with gr.Blocks() as demo: with gr.Row(equal_heightTrue): textbox gr.Textbox() btn2 gr.Button(按钮2)从源码看equal_height是 gradio/layouts/row.py 中Row构造函数的显式参数默认False它会被直接存入实例供前端样式层消费。控制行内宽度scale 与 min_width每一个组件以及布局元素都内置了scale与min_width两个参数用于控制它在行内占据的宽度scale整数决定元素在行内的相对伸展权重。scale0元素不会扩展去抢占多余空间保持内容宽度。scale1及以上元素会扩展同一行内多个可扩展元素按 scale 数值等比例分配剩余宽度。例如下方btn2的伸展量是btn1的两倍而btn0完全不伸展import gradio as gr with gr.Blocks() as demo: with gr.Row(): btn0 gr.Button(按钮0, scale0) btn1 gr.Button(按钮1, scale1) btn2 gr.Button(按钮2, scale2)min_width整数单位像素设置元素的最小宽度。当屏幕空间不足以同时满足所有元素的min_width时Row 会自动换行这是 flexboxflex-wrap的典型行为因此它能保证窄屏下的可用性。值得一提的细节在 gradio/layouts/column.py 和 gradio/layouts/row.py 的构造函数中源码会对scale做非整数校验并给出warnings.warnscale value should be an integer...说明该参数虽然类型标注为int但 API 层面允许浮点传入并建议使用整数避免布局出现非预期比例。Column 与嵌套构造真正的应用布局gr.Column会把其中的组件自上而下垂直排列。由于垂直堆叠本身就是 Blocks 的默认排布方式Column 通常嵌套在 Row 内部才真正有用——由此形成行内分列的经典布局结构。仓库中 demo/rows_and_columns/run.py 提供了一个完整范例import gradio as gr with gr.Blocks() as demo: with gr.Row(): text1 gr.Textbox(labelt1) slider2 gr.Textbox(labels2) drop3 gr.Dropdown([a, b, c], labeld3) with gr.Row(): with gr.Column(scale1, min_width300): text1 gr.Textbox(labelprompt 1) text2 gr.Textbox(labelprompt 2) inbtw gr.Button(Between) text4 gr.Textbox(labelprompt 1) text5 gr.Textbox(labelprompt 2) with gr.Column(scale2, min_width300): img1 gr.Image(images/cheetah.jpg) # 请替换为本地存在的一张图片路径 btn gr.Button(Go) if __name__ __main__: demo.launch()从结构上观察如需运行请将上述gr.Image(...)中的路径替换为你机器上真实存在的图片文件否则启动后该组件会因找不到资源而报错第一列垂直排列了两个文本框第二列垂直排列了图片与按钮。两列的相对宽度完全由scale决定左侧scale1、右侧scale2因此右侧列占据两倍宽度。每列都设置了min_width300当窗口收窄到无法同时容纳两列的最小宽度时第二列会折行到下一行显示。在 gradio/layouts/column.py 中可以看到Column的默认值scale: int 1、min_width: int 320源码注释明确了优先级规则——若某个scale计算出的列宽小于min_width则min_width优先生效。此外Column与Row都支持variant参数default无背景、panel灰背景圆角、compact圆角且去掉内部间隙便于快速获得卡片化视觉。填充浏览器全高全宽官方英文版指南还补充了两个页面级布局开关用于消除默认的留白import gradio as gr # 去掉左右内边距让应用占满浏览器宽度 with gr.Blocks(fill_widthTrue) as demo: gr.Chatbot()import gradio as gr # 顶层组件占满浏览器高度配合 scale 让 Chatbot 吃掉全部剩余高度 with gr.Blocks(fill_heightTrue) as demo: gr.Chatbot(scale1) gr.Textbox(scale0)上面第二个例子中gr.Chatbot(scale1)会把可扩展高度全部占满而gr.Textbox(scale0)保持自身固有高度固定在底部。这是制作终端式聊天界面的常用手法。自定义尺寸像素或任意 CSS 单位部分组件与布局元素支持直接设置height与width。这两个参数既接受数字按像素解释也接受字符串此时字符串会被直接当作 CSS 单位作用到外层元素上。这意味着你可以使用px、%、vw、vh、rem等任意合法 CSS 长度单位。例如按视口宽度viewport width设定图片编辑器的宽度使其始终占据浏览器一半宽度import gradio as gr with gr.Blocks() as demo: im gr.ImageEditor(width50vw) demo.launch()同样的规则适用于Row的height、max_height、min_height参数见 gradio/layouts/row.py传数字按像素解析、传字符串按 CSS 单位解析内容超出时会触发垂直滚动。这一能力为自适应宽高场景提供了比固定像素更灵活的选项。Tab 选项卡与 Accordion 手风琴用 gr.Tab 组织互斥内容页使用with gr.Tab(标签名):即可创建选项卡。凡是写在该上下文内的组件都会归入这个页签连续的 Tab 子句会被分组成一组同一时刻只能选中一个页签、只显示对应上下文中的组件。demo/blocks_flipper/run.py 给出了一个翻转文本 / 翻转图像的双页签示例import numpy as np import gradio as gr def flip_text(x): return x[::-1] def flip_image(x): return np.fliplr(x) with gr.Blocks() as demo: gr.Markdown(Flip text or image files using this demo.) with gr.Tab(Flip Text): text_input gr.Textbox() text_output gr.Textbox() text_button gr.Button(Flip) with gr.Tab(Flip Image): with gr.Row(): image_input gr.Image() image_output gr.Image() image_button gr.Button(Flip) with gr.Accordion(Open for More!, openFalse): gr.Markdown(Look at me...) temp_slider gr.Slider( 0, 1, value0.1, step0.1, interactiveTrue, labelSlide me, ) text_button.click(flip_text, inputstext_input, outputstext_output) image_button.click(flip_image, inputsimage_input, outputsimage_output) if __name__ __main__: demo.launch()从源码 gradio/layouts/tabs.py 可进一步挖掘出不少实用参数gr.Tabs(selected...)程序化指定默认选中的页签需配合子页签的id。gr.Tab(label, id...)id用于在事件函数中通过返回gr.Tabs(selectedid)实现点击按钮跳转页签。gr.Tab(interactiveFalse)使该页签不可点击。gr.Tab(render_childrenTrue)页签未激活时也预先渲染并隐藏子组件便于视频、音频等重资源提前加载。Tab拥有select事件其文档字符串中的EVENTS定义可见事件数据会携带被点击页签的label与selected状态。值得注意Tabs.__exit__中实现了严格的子级校验gr.Tabs()的直接子级只能是gr.Tab()别名gr.TabItem若误将普通组件直接放进Tabs会触发UserWarning提示开发者把内容包进gr.Tab(...)。用 Accordion 折叠/展开附加内容gr.Accordion(标签)是一种可开可合的布局元素作用类似手风琴。定义在with gr.Accordion(label):内部的任何组件会在用户点击切换图标时统一隐藏或显示。上面的示例在页签组下方放了一个默认折叠的gr.Accordion(Open for More!, openFalse)用于收纳可选设置项。gradio/layouts/accordion.py 源码显示其核心参数为label手风琴的标题。open是否默认展开默认True上面的示例传False让高级选项默认收起。事件上支持expand/collapse两个事件监听可感知用户的展开/折叠行为并触发回调。Sidebar左侧可折叠面板在较新版本中布局家族还加入了gr.Sidebar一个渲染在屏幕左侧、可展开/折叠的面板用于把控制项/输入项与主内容区清晰分隔。典型用法是把下拉框、单选按钮等输入控件放入 Sidebar把结果输出放在主区域。仓库中的 demo/blocks_sidebar/run.py 用 Sidebar 实现了一个宠物起名器——左侧面板内放置动物类型、性格等选项右侧主区域展示生成的名称与按钮。核心结构如下with gr.Blocks() as demo: with gr.Sidebar(positionleft): animal_type gr.Dropdown( choices[Cat, Dog, Bird, Rabbit], labelChoose your pet type, valueCat ) personality gr.Radio( choices[Normal, Silly, Royal], labelPersonality type, valueNormal ) name_output gr.Textbox(labelYour pets fancy name:, lines2) generate_btn gr.Button(Generate Name! , variantprimary) generate_btn.click( fngenerate_pet_name, inputs[animal_type, personality], outputsname_output )结合 gradio/layouts/sidebar.py 的构造函数Sidebar支持以下参数open默认是否展开默认True。width侧栏宽度数字按像素、字符串按 CSS 单位解析默认320。positionleft或right决定侧栏位于主区域左侧还是右侧默认left。与 Accordion 一样Sidebar也暴露expand/collapse事件便于在面板开合时联动界面。Walkthrough分步引导式布局面向需要用户按顺序完成多步任务的应用布局层还提供了gr.Walkthrough与配套的gr.Step组件它们提供了一套专门设计的视觉风格与操作体验。其编写方式与Tab类似区别在于推进步骤的责任在应用开发者——通过在事件回调中设置父级Walkthrough的选中id该id须与某个Step的id对应来切换当前步骤。demo/walkthrough/run.py 展示了一个上传图片 → 填写提示词 → 查看结果的三步引导流程import gradio as gr with gr.Blocks() as demo: with gr.Walkthrough(selected0) as walkthrough: with gr.Step(Image, id0): image gr.Image() btn gr.Button(go to prompt) btn.click(lambda: gr.Walkthrough(selected1), outputswalkthrough) with gr.Step(Prompt, id1): prompt gr.Textbox() btn gr.Button(generate) btn.click(lambda: gr.Walkthrough(selected2), outputswalkthrough) with gr.Step(Result, id2): gr.Image(labelresult, interactiveFalse) if __name__ __main__: demo.launch()每个下一步按钮都通过btn.click(lambda: gr.Walkthrough(selectedN), outputswalkthrough)把父级Walkthrough组件作为输出、更新其选中步骤从而实现受控的线性流程。适合做教学向导、多阶段审核、Pipeline 配置等场景。可见性控制显示或隐藏组件与整组布局组件与布局元素都拥有一个visible参数既可在创建时设定初始状态也可以在事件回调中通过gr.update(visible...)动态更新。由于Column本身也是BlockContext对整列设置可见性即可一次性显示/隐藏一组组件这是实现表单提交前隐藏、提交后展示结果区等交互的最直接手段。仓库中 demo/blocks_form/run.py 是一个完整的病历表单示例点击 Submit 前右侧的诊断结果列处于隐藏状态提交后该列显现、输入按钮列隐藏并回填诊断内容import gradio as gr with gr.Blocks() as demo: name_box gr.Textbox(labelName) age_box gr.Number(labelAge, minimum0, maximum100) symptoms_box gr.CheckboxGroup([Cough, Fever, Runny Nose]) submit_btn gr.Button(Submit) with gr.Column(visibleFalse) as output_col: diagnosis_box gr.Textbox(labelDiagnosis) patient_summary_box gr.Textbox(labelPatient Summary) def submit(name, age, symptoms): return { submit_btn: gr.Button(visibleFalse), output_col: gr.Column(visibleTrue), diagnosis_box: covid if Cough in symptoms else flu, patient_summary_box: f{name}, {age} y/o, } submit_btn.click( submit, [name_box, age_box, symptoms_box], [submit_btn, diagnosis_box, patient_summary_box, output_col], ) if __name__ __main__: demo.launch()关键点解读with gr.Column(visibleFalse) as output_col:把两个结果文本框包进一列并默认隐藏。事件函数submit返回一个字典其中键可以是组件、布局对象甚至事件源按钮值可以是新值或gr.update因此函数可以同时更新隐藏状态与内容——输出列表[...submit_btn, diagnosis_box, patient_summary_box, output_col]中甚至把按钮本身也作为输出用于把它自身隐藏。布局元素在字典更新里通过gr.Column(visibleTrue)对 Row 同理见 gradio/layouts/row.py 中Row.update静态方法仅接收visible完成显示切换。可变数量输出用可见性驱动动态界面把动态调整可见性的思路推广就能实现可变数量输出Variable Number of Outputs的演示界面上输出控件的数量随某个输入实时变化。demo/variable_outputs/run.py 用一个滑块控制文本框的显示个数import gradio as gr max_textboxes 10 def variable_outputs(k): k int(k) return [gr.Textbox(visibleTrue)]*k [gr.Textbox(visibleFalse)]*(max_textboxes-k) with gr.Blocks() as demo: s gr.Slider(1, max_textboxes, valuemax_textboxes, step1, labelHow many textboxes to show:) textboxes [] for i in range(max_textboxes): t gr.Textbox(fTextbox {i}) textboxes.append(t) s.change(variable_outputs, s, textboxes) if __name__ __main__: demo.launch()实现原理是一次性定义全部这里为 10 个文本框把它们的引用放进textboxes列表并整体作为事件输出当滑块值变为k时回调返回k个visibleTrue的更新与10-k个visibleFalse的更新前端据此重新布局从而在结构固定的前提下实现数量可变的假象——这种模式对动态添加/移除输入行类需求非常实用。分开定义与渲染组件render 与 unrender场景gr.Examples 放在输入框上方gr.Blocks上下文内定义的组件会立即渲染到 DOM。但有些场景需要先拿到组件对象、后决定它的渲染位置。典型例子是把gr.Examples示例区显示在对应的输入框上方由于gr.Examples构造时需要传入输入组件对象作为参数就必须先创建输入组件对象、再创建Examples、最后才真正渲染输入框。解决办法在gr.Blocks()作用域之外定义组件此时组件被创建但不会被自动渲染然后在 UI 中期望它出现的位置调用该组件的.render()方法import gradio as gr input_textbox gr.Textbox() # 先在 Blocks 之外创建暂不渲染 with gr.Blocks() as demo: gr.Examples([hello, bonjour, merhaba], input_textbox) input_textbox.render() # 之后在示例区下方渲染输入框运行后界面会先展示三个示例例句示例区下方才是真正的文本输入框——这正是分开定义与渲染的价值。逆向操作unrender 后在其他位置重新渲染若一个组件已被渲染但你希望把它挪到应用的另一处可先调用.unrender()将其从原位置卸载再调用.render()在新位置重新挂载。例如下面这段代码textbox原本定义在第一列但先在第二列被unrender()摘除最终在第三列才真正出现import gradio as gr with gr.Blocks() as demo: with gr.Row(): with gr.Column(): gr.Markdown(Row 1) textbox gr.Textbox() with gr.Column(): gr.Markdown(Row 2) textbox.unrender() with gr.Column(): gr.Markdown(Row 3) textbox.render() demo.launch()render/unrender这种延迟渲染 移动挂载机制与gr.render装饰器见指南 04_dynamic-apps-with-render-decorator.md配合是构建动态、可重排 UI 的重要底层能力。小结与进阶路线围绕 Blocks 布局控制可以提炼出如下决策脉络基础排布默认垂直gr.Row改横向equal_height对齐高度scale/min_width控制伸缩与换行结构化分栏Row内嵌多个gr.Column用scale控制列宽比例、min_width保证窄屏可用默认 320px页面级自适应gr.Blocks(fill_widthTrue / fill_heightTrue)撑满浏览器组件级width/height支持任意 CSS 单位内容分区gr.Tab做互斥页签、gr.Accordion做可折叠分组、gr.Sidebar做左右分栏控制面板、gr.Walkthroughgr.Step做分步引导动态交互所有组件/布局的visible参数可用gr.update在回调中切换由此实现整组显示隐藏、可变数量输出灵活渲染Blocks 作用域外先定义、用.render()/.unrender()控制组件挂载位置与时机。想深入了解相关实现可在仓库中继续阅读布局源码实现gradio/layouts/row.py、gradio/layouts/column.py、gradio/layouts/tabs.py、gradio/layouts/accordion.py、gradio/layouts/sidebar.py可运行示例demo/rows_and_columns/run.py、demo/blocks_flipper/run.py、demo/blocks_form/run.py、demo/variable_outputs/run.py、demo/blocks_sidebar/run.py、demo/walkthrough/run.py配套学习指南事件监听器与 Blocks 基础中文、Blocks 中的状态管理中文以及上文反复引用的英文完整版 02_controlling-layout.md。结合这些源码与示例动手修改scale、min_width、visible等参数并实时预览即可快速建立对 Gradio 布局模型的直观手感。【免费下载链接】gradioBuild and share delightful machine learning apps, all in Python. Star to support our work!项目地址: https://gitcode.com/GitHub_Trending/gr/gradio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考