控制布局

默认情况下,块中的组件是垂直排列的。 让我们来看看如何重新排列组件。 在底层,这种布局结构使用了web 开发的 flexbox 模型

By default, Components in Blocks are arranged vertically. Let's take a look at how we can rearrange Components. Under the hood, this layout structure uses the flexbox model of web development.

行数

with gr.Row 子句中的元素将全部水平显示。 例如,要并排显示两个按钮:

Elements within a with gr.Row clause will all be displayed horizontally. For example, to display two Buttons side by side:

with gr.Blocks() as demo:
    with gr.Row():
        btn1 = gr.Button("Button 1")
        btn2 = gr.Button("Button 2")

要使 Row 中的每个元素具有相同的高度,请使用 style 方法的 equal_height 参数。

To make every element in a Row have the same height, use the equal_height argument of the style method.

with gr.Blocks() as demo:
    with gr.Row().style(equal_height=True):
        textbox = gr.Textbox()
        btn2 = gr.Button("Button 2")

文档中了解有关行的更多信息。

Learn more about Rows in the docs.

列和嵌套

Column 中的组件将垂直放置在彼此之上。 由于垂直布局是 Blocks 应用程序的默认布局,为了有用,列通常嵌套在行中。 例如:

Components within a Column will be placed vertically atop each other. Since the vertical layout is the default layout for Blocks apps anyway, to be useful, Columns are usually nested within Rows. For example:

import gradio as gr

with gr.Blocks() as demo:
    with gr.Row():
        text1 = gr.Textbox(label="t1")
        slider2 = gr.Textbox(label="s2")
        drop3 = gr.Dropdown(["a", "b", "c"], label="d3")
    with gr.Row():
        with gr.Column(scale=1, min_width=600):
            text1 = gr.Textbox(label="prompt 1")
            text2 = gr.Textbox(label="prompt 2")
            inbtw = gr.Button("Between")
            text4 = gr.Textbox(label="prompt 1")
            text5 = gr.Textbox(label="prompt 2")
        with gr.Column(scale=2, min_width=600):
            img1 = gr.Image("images/cheetah.jpg")
            btn = gr.Button("Go").style(full_width=True)

demo.launch()

查看第一列如何有两个垂直排列的文本框。 第二列有一个垂直排列的图像和按钮。 注意两列的相对宽度是如何由 scale 参数设置的。 具有两倍 scale 值的列占用两倍的宽度。

See how the first column has two Textboxes arranged vertically. The second column has an Image and Button arranged vertically. Notice how the relative widths of the two columns is set by the scale parameter. The column with twice the scale value takes up twice the width.

列也有一个 min_width 参数(默认为 320 像素)。 这可以防止相邻的列在移动屏幕上变得太窄。

Columns have a min_width parameter as well (320 pixels by default). This prevents adjacent columns from becoming too narrow on mobile screens.

文档中了解有关列的更多信息。

Learn more about Columns in the docs.

标签和手风琴

你还可以使用 with gr.Tab('tab_name'): 子句创建选项卡。 在 with gr.Tab('tab_name'): 上下文中创建的任何组件都会出现在该选项卡中。 连续的 Tab 子句组合在一起,以便一次可以选择单个选项卡,并且仅显示该选项卡上下文中的组件。

You can also create Tabs using the with gr.Tab('tab_name'): clause. Any component created inside of a with gr.Tab('tab_name'): context appears in that tab. Consecutive Tab clauses are grouped together so that a single tab can be selected at one time, and only the components within that Tab's context are shown.

例如:

For example:

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!"):
        gr.Markdown("Look at me...")

    text_button.click(flip_text, inputs=text_input, outputs=text_output)
    image_button.click(flip_image, inputs=image_input, outputs=image_output)

demo.launch()

另请注意此示例中的 gr.Accordion('label') 。 手风琴是一种可以打开或关闭的布局。 与 Tabs 一样,它是一个可以选择性地隐藏或显示内容的布局元素。 with gr.Accordion('label'): 在 a 内部定义的任何组件都将在单击手风琴的切换图标时隐藏或显示。

Also note the gr.Accordion('label') in this example. The Accordion is a layout that can be toggled open or closed. Like Tabs, it is a layout element that can selectively hide or show content. Any components that are defined inside of a with gr.Accordion('label'): will be hidden or shown when the accordion's toggle icon is clicked.

在文档中了解有关选项卡手风琴的更多信息。

Learn more about Tabs and Accordions in the docs.

能见度

Components 和 Layout 元素都有一个 visible 参数,可以初始设置,也可以使用 gr.update() 更新。 在列上设置 gr.update(visible=...) 可用于显示或隐藏一组组件。

Both Components and Layout elements have a visible argument that can set initially and also updated using gr.update(). Setting gr.update(visible=...) on a Column can be used to show or hide a set of Components.

import gradio as gr

with gr.Blocks() as demo:
    error_box = gr.Textbox(label="Error", visible=False)

    name_box = gr.Textbox(label="Name")
    age_box = gr.Number(label="Age")
    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.update(value="Enter name", visible=True)}
        if age < 0 or age > 200:
            return {error_box: gr.update(value="Enter valid age", visible=True)}
        return {
            output_col: gr.update(visible=True),
            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],
        [error_box, diagnosis_box, patient_summary_box, output_col],
    )

demo.launch()

可变数量的输出

通过以动态方式调整组件的可见性,可以使用支持可变数量输出的Gradio 创建演示。 这是一个非常简单的示例,其中输出文本框的数量由输入滑块控制:

By adjusting the visibility of components in a dynamic way, it is possible to create demos with Gradio that support a variable numbers of outputs. Here's a very simple example where the number of output textboxes is controlled by an input slider:

import gradio as gr

max_textboxes = 10

def variable_outputs(k):
    k = int(k)
    return [gr.Textbox.update(visible=True)]*k + [gr.Textbox.update(visible=False)]*(max_textboxes-k)

with gr.Blocks() as demo:
    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)

if __name__ == "__main__":
   demo.launch()

分别定义和渲染组件

在某些情况下,你可能希望在实际将组件呈现在 UI 中之前定义它们。 例如,你可能希望在相应的 gr.Textbox 输入上方使用 gr.Examples 显示示例部分。 由于 gr.Examples 需要输入组件对象作为参数,因此你需要先定义输入组件,然后在定义 gr.Examples 对象后渲染它。

In some cases, you might want to define components before you actually render them in your UI. For instance, you might want to show an examples section using gr.Examples above the corresponding gr.Textbox input. Since gr.Examples requires as a parameter the input component object, you will need to first define the input component, but then render it later, after you have defined the gr.Examples object.

对此的解决方案是在 gr.Blocks() 范围之外定义 gr.Textbox 并使用组件的 .render() 方法将其放置在 UI 中的任何位置。

The solution to this is to define the gr.Textbox outside of the gr.Blocks() scope and use the component's .render() method wherever you'd like it placed in the UI.

这是一个完整的代码示例:

Here's a full code example:

input_textbox = gr.Textbox()

with gr.Blocks() as demo:
    gr.Examples(["hello", "bonjour", "merhaba"], input_textbox)
    input_textbox.render()