默认情况下,块中的组件垂直排列。让我们看看如何重新排列组件。在底层,这种布局结构使用了网页开发的 flexbox 模型。
行
在 with gr.Row
子句中的元素将全部水平显示。例如,要并排显示两个按钮:
with gr.Blocks() as demo:with gr.Row():btn1 = gr.Button("Button 1")btn2 = gr.Button("Button 2")
要使行中的每个元素都具有相同的高度,请使用 style
方法的 equal_height
参数。
with gr.Blocks() as demo:with gr.Row(equal_height=True):textbox = gr.Textbox()btn2 = gr.Button("Button 2")
可以通过每个组件中存在的 scale
和 min_width
参数的组合来控制行中元素的宽度。
scale
是一个整数,定义了元素在 Row 中占据的空间。如果 scale 设置为0
,元素不会扩展占据空间。如果 scale 设置为1
或更大,元素将会扩展。Row 中的多个元素会根据它们的 scale 成比例扩展。下面,btn2
将会扩展两倍于btn1
,而btn0
则根本不会扩展:
with gr.Blocks() as demo:with gr.Row():btn0 = gr.Button("Button 0", scale=0)btn1 = gr.Button("Button 1", scale=1)btn2 = gr.Button("Button 2", scale=2)
min_width
将设置元素的最小宽度。如果没有足够的空间满足所有min_width
值,Row 将会换行。
https://www.gradio.app/docs/gradio/row
列和嵌套
"在 Column 中的组件将会被垂直地放置在彼此之上。由于垂直布局本来就是 Blocks 应用的默认布局,为了发挥作用,Columns 通常会嵌套在 Rows 内。例如:
import gradio as gr # 导入gradio库with gr.Blocks() as demo: # 使用gr.Blocks构建应用布局with gr.Row(): # 创建一行,用于并排放置以下组件text1 = gr.Textbox(label="t1") # 创建一个文本输入框,标签为t1slider2 = gr.Textbox(label="s2") # 错误地将其命名为slider2,实际上是一个文本输入框,标签为s2drop3 = gr.Dropdown(["a", "b", "c"], label="d3") # 创建一个下拉菜单,选项为a, b, c,标签为d3with gr.Row(): # 创建另一行,用于布局两个列容器with gr.Column(scale=1, min_width=600): # 创建第一个列容器,比例为1,最小宽度600pxtext1 = gr.Textbox(label="prompt 1") # 创建一个文本输入框,标签为prompt 1text2 = gr.Textbox(label="prompt 2") # 创建另一个文本输入框,标签为prompt 2inbtw = gr.Button("Between") # 创建一个按钮,标签为Betweentext4 = gr.Textbox(label="prompt 1") # 创建第三个文本输入框,错误命名,应为text3,标签为prompt 1text5 = gr.Textbox(label="prompt 2") # 创建第四个文本输入框,错误命名,应为text4,标签为prompt 2with gr.Column(scale=2, min_width=600): # 创建第二个列容器,比例为2,最小宽度600pximg1 = gr.Image("images/cheetah.jpg") # 创建一个图像显示组件,初始显示cheetah.jpgbtn = gr.Button("Go") # 创建一个按钮,标签为Godemo.launch() # 启动应用
这段代码使用Gradio库构建了一个具有多个输入和显示组件的Web应用布局。布局包含两行,第一行包含一个文本框、另一个被错误地称为滑块(实际上是文本框)的文本框和一个下拉菜单。第二行包括两个列容器,第一个列容器以1:2的比例展示了两个文本输入框、一个按钮和其他错误命名的文本框;第二个列容器,以更大的比例展示了一个图像和一个按钮。此代码主要展示了Gradio布局的使用,包括行、列的嵌套结构,以及如何通过设置比例和最小宽度来控制布局的响应式表现。需要注意的是,代码中存在一些命名的误区,如slider2
实际上是一个文本输入框,并且后续创建的text4
和text5
在逻辑上分别应当是text3
和text4
。此外,应用布局构建完成后,并没有为按钮和其他组件绑定具体的动作或逻辑,这些需要在实际应用开发过程中根据需求进一步添加。
看看第一列是如何垂直排列了两个文本框。第二列垂直排列了一个图像和按钮。注意两列的相对宽度是由 scale
参数设置的。宽度是 scale
值两倍的列,其宽度也是两倍。
在文档中了解更多关于列的信息。
尺寸
您可以控制各种组件的高度和宽度,这些参数是可用的。这些参数接受一个数字(解释为像素)或一个字符串。使用字符串可以直接将任何 CSS 单位应用于封装的块元素,以满足更具体的设计要求。如果省略,Gradio 会使用适合大多数用例的默认尺寸。
下面是一个示例,说明了视口宽度(vw)的使用:
import gradio as gr # 导入gradio库with gr.Blocks() as demo: # 使用gr.Blocks创建一个应用布局im = gr.ImageEditor(width="50vw", # 设置图像编辑器的宽度为视口宽度的50%)demo.launch() # 启动应用
代码使用Gradio库创建了一个简单的Web应用程序,其中包含一个图像编辑器组件。应用启动后,用户将看到一个可以进行基本图像编辑操作(如裁剪、调整尺寸等)的界面。通过设定width
参数为"50vw",图像编辑器的宽度被设置为视图宽度的50%,"vw"是一个CSS单位,代表视口宽度的1%,这样可以确保图像编辑器的宽度相对于用户视口大小进行动态调整,以适应不同设备和屏幕尺寸。这个示例展示了Gradio的ImageEditor
组件的使用方式,展现了如何快速集成一个图像编辑工具到Web应用中
当使用百分比值定义尺寸时,您可能希望用一个绝对单位(例如 px
或 vw
)定义一个父组件。这种方法确保了具有相对尺寸的子组件能够适当地调整大小:
import gradio as gr # 导入gradio库css = """
.container {height: 100vh;
}
""" # 定义CSS样式,设置容器高度为视口高的100%with gr.Blocks(css=css) as demo: # 使用gr.Blocks创建一个应用布局,并应用自定义CSSwith gr.Column(elem_classes=["container"]): # 创建一个列元素,并应用自定义的.container类name = gr.Chatbot(value=[["1", "2"]], height="70%") # 创建一个Chatbot组件,初始对话为["1", "2"],高度设为70%demo.launch() # 启动应用
这段代码使用了Gradio库来创建一个包含Chatbot组件的Web应用。通过CSS自定义了.container
类以设置容器的高度为视口高度的100%,这意味着列容器将充满整个屏幕的高度。Chatbot组件在这个容器内被创建,并设置了其高度占据容器高度的70%,初始显示的对话内容为["1", "2"]。这个示例展现了如何使用Gradio创建带有Chatbot的界面,并通过CSS对组件进行样式自定义。这对于想要在Web应用中实现聊天机器人界面的开发者来说是一个非常实用的示例。
在此示例中,Column 布局组件的高度被设置为视口高度的 100%(100vh),而其中的 Chatbot 组件占据了 Column 高度的 70%。
您可以对这些参数应用任何有效的 CSS 单位。有关 CSS 单位的综合列表,请参阅本指南https://www.w3schools.com/cssref/css_units.php 。我们建议您始终考虑响应性,并在各种屏幕尺寸上测试您的界面,以确保用户体验的一致性。
标签页和手风琴
您也可以使用 with gr.Tab('tab_name'):
子句创建标签页。在 with gr.Tab('tab_name'):
上下文中创建的任何组件都会显示在该标签页中。连续的标签页子句会被组合在一起,这样一次只能选择一个标签页,并且只显示该标签页上下文中的组件。
例如:
import numpy as np # 导入numpy库
import gradio as gr # 导入gradio库def flip_text(x): # 定义翻转文本的函数return x[::-1] # 返回反向的字符串def flip_image(x): # 定义翻转图像的函数return np.fliplr(x) # 使用numpy的fliplr函数翻转图像数组中的元素with gr.Blocks() as demo: # 使用gr.Blocks创建一个应用布局gr.Markdown("Flip text or image files using this demo.") # 添加Markdown组件,显示说明文字with gr.Tab("Flip Text"): # 在标签页中创建一个文本翻转功能text_input = gr.Textbox() # 创建文本输入框text_output = gr.Textbox() # 创建文本输出框,用于显示翻转后的文本text_button = gr.Button("Flip") # 创建一个按钮,标签为Flipwith gr.Tab("Flip Image"): # 在另一个标签页中创建图像翻转功能with gr.Row(): # 创建一行来并排放置输入和输出图像image_input = gr.Image() # 创建图像输入组件image_output = gr.Image() # 创建图像输出组件,用于显示翻转后的图像image_button = gr.Button("Flip") # 创建一个按钮,标签为Flipwith gr.Accordion("Open for More!", open=False): # 创建一个折叠区域,初始状态为关闭gr.Markdown("Look at me...") # 在折叠区域中添加Markdown组件temp_slider = gr.Slider(minimum=0.0, # 滑动条的最小值maximum=1.0, # 滑动条的最大值value=0.1, # 初始值step=0.1, # 步长interactive=True, # 设置为交互模式label="Slide me", # 标签)temp_slider.change(lambda x: x, [temp_slider]) # 绑定滑动条的变化事件,仅作为演示text_button.click(flip_text, inputs=text_input, outputs=text_output) # 将文本按钮的点击事件绑定到flip_text函数image_button.click(flip_image, inputs=image_input, outputs=image_output) # 将图像按钮的点击事件绑定到flip_image函数demo.launch() # 启动应用
这段代码演示了如何使用Gradio库创建一个Web应用,功能包括翻转文本和图像。应用界面使用标签页来区分文本翻转和图像翻转功能,其中每个功能都有对应的输入框、输出框以及一个触发操作的按钮。此外,还使用了折叠区域(Accordion)来隐藏额外的信息或工具,例如一个滑动条(Slider)。
对于文本翻转,程序定义了一个
flip_text
函数,它接收用户输入的字符串,并返回其反向字符串作为输出。对于图像翻转,程序定义了一个
flip_image
函数,它使用numpy
的fliplr
函数来实现图像的左右翻转。
这个应用可以用来翻转用户上传的文本或图像,并将翻转后的结果即时显示给用户。这是一个很好的示例,展示了Gradio框架如何用于快速搭建具有交互式输入和输出的机器学习或数据处理应用。
也请注意本例中的 gr.Accordion('label')
。手风琴是一种可以切换打开或关闭的布局。像 Tabs
一样,它是一种可以选择性隐藏或显示内容的布局元素。定义在 with gr.Accordion('label'):
内的任何组件都会在点击手风琴的切换图标时被隐藏或显示。
在文档中了解更多关于标签页和手风琴的信息。
https://www.gradio.app/docs/gradio/tab
https://gradio.app/docs/accordion
可见性
组件和布局元素都有一个可以初始设置并且也可以更新的 visible
参数。在列上设置 gr.Column(visible=...)
可以用来显示或隐藏一组组件。
import gradio as gr # 导入gradio库with gr.Blocks() as demo: # 使用gr.Blocks创建一个应用布局error_box = gr.Textbox(label="Error", visible=False) # 创建一个不可见的错误消息文本框name_box = gr.Textbox(label="Name") # 创建姓名输入框age_box = gr.Number(label="Age", minimum=0, maximum=100) # 创建年龄输入框,限定年龄范围在0到100岁symptoms_box = gr.CheckboxGroup(["Cough", "Fever", "Runny Nose"]) # 创建症状多选框submit_btn = gr.Button("Submit") # 创建提交按钮with gr.Column(visible=False) as output_col: # 创建一个初始不可见的列,用于显示返回结果diagnosis_box = gr.Textbox(label="Diagnosis") # 诊断结果文本框patient_summary_box = gr.Textbox(label="Patient Summary") # 患者摘要文本框def submit(name, age, symptoms):if len(name) == 0: # 如果未输入姓名return {error_box: gr.Textbox(value="Enter name", visible=True)} # 显示错误消息return {output_col: gr.Column(visible=True), # 显示输出结果的列diagnosis_box: "covid" if "Cough" in symptoms else "flu", # 根据症状给出初步诊断patient_summary_box: f"{name}, {age} y/o", # 显示患者摘要}submit_btn.click(submit, # 绑定点击事件到submit函数[name_box, age_box, symptoms_box], # 指定输入参数[error_box, diagnosis_box, patient_summary_box, output_col], # 指定输出参数)demo.launch() # 启动应用
这段代码演示了如何使用Gradio库创建一个具有用户输入和动态结果展示的Web应用程序。用户可以通过填写姓名、年龄和选择症状,然后点击提交按钮来获取初步诊断结果。应用逻辑如下:
用户输入姓名、选择年龄、选择一个或多个症状,然后点击“Submit”按钮。
如果用户没有输入姓名,将会显示错误消息提示用户输入姓名。
如果用户已经输入姓名,则显示患者的初步诊断结果和摘要信息。这里简化地根据是否选择了“咳嗽”作为症状来判断诊断结果是“covid”还是“flu”。
这个示例展示了Gradio在处理表单输入及动态显示结果方面的能力,特别是在医疗信息收集、初步诊断等应用场景中的潜在用途。
输出变量数量
通过动态调整组件的可见性,可以创建支持可变输出数量的 Gradio 演示。这里有一个非常简单的例子,输出文本框的数量由输入滑块控制:
import gradio as gr # 导入gradio库max_textboxes = 10 # 定义最大文本框数量def variable_outputs(k): # 定义一个函数,根据滑块的值动态显示文本框k = int(k) # 确保k是整数return [gr.Textbox(visible=True)]*k + [gr.Textbox(visible=False)]*(max_textboxes-k) # 根据滑块的值动态生成可见和不可见的文本框列表with gr.Blocks() as demo: # 使用gr.Blocks创建一个应用布局s = gr.Slider(1, max_textboxes, value=max_textboxes, step=1, label="How many textboxes to show:") # 创建一个滑块,用于选择显示多少个文本框textboxes = [] # 初始化一个空列表,用于存储文本框组件for i in range(max_textboxes): # 循环生成指定数量的文本框t = gr.Textbox(f"Textbox {i}") # 创建文本框,并给予标签textboxes.append(t) # 将文本框添加到列表中s.change(variable_outputs, s, textboxes) # 将滑块的变化事件绑定到variable_outputs函数if __name__ == "__main__":demo.launch() # 启动应用
这段代码使用Gradio库创建了一个Web应用,该应用通过滑块控件允许用户动态选择显示的文本框数量。具体行为如下:
应用中有一个滑块(
gr.Slider
),让用户选择要显示的文本框数量,范围从1到10。根据滑块的值,应用将显示相应数量的文本框,滑块值为多少就显示多少个文本框,最多显示10个。
每个文本框在创建时被赋予一个唯一的标签,如"Textbox 0"、"Textbox 1"等。
当用户调整滑块时,
variable_outputs
函数会被调用,该函数根据滑块的当前值动态调整文本框的可见性,使得只有指定数量的文本框是可见的,其余的则被设置为不可见。
这个示例展示了如何使用Gradio实现动态界面元素的显示与隐藏,通过Slider
组件和绑定的事件处理函数来控制其他组件(如Textbox
)的属性,这在创建需要根据用户输入动态调整内容的应用时非常有用。
分别定义和渲染组件
在某些情况下,您可能希望在实际渲染 UI 之前定义组件。例如,您可能希望使用 gr.Examples
在相应的 gr.Textbox
输入上方显示一个示例部分。由于 gr.Examples
需要输入组件对象作为参数,您将需要首先定义输入组件,然后在定义了 gr.Examples
对象之后再渲染它。
解决方案是在 gr.Blocks()
范围之外定义 gr.Textbox
,并在 UI 中希望放置它的任何位置使用组件的 .render()
方法。
源代码示例:
input_textbox = gr.Textbox()with gr.Blocks() as demo:gr.Examples(["hello", "bonjour", "merhaba"], input_textbox)input_textbox.render()