Gradio 代理 & MCP 黑客马拉松
获奖者Gradio 代理 & MCP 黑客马拉松
获奖者Gradio 内置主题引擎,可让你自定义应用的视觉外观和风格。你可以从多种主题中选择,或创建自己的主题。为此,将 theme=
关键字参数传递给 Blocks
或 Interface
构造函数。例如:
with gr.Blocks(theme=gr.themes.Soft()) as demo:
...
Gradio 提供了一系列预构建主题,你可以从 gr.themes.*
加载它们。这些主题包括:
gr.themes.Base()
- "base"
主题将主色设置为蓝色,但样式极简,因此作为创建新的自定义主题的基础非常有用。gr.themes.Default()
- Gradio 5 的 "default"
主题,具有鲜艳的橙色主色和灰色次色。gr.themes.Origin()
- "origin"
主题与 Gradio 4 样式最相似。颜色,尤其是在浅色模式下,比 Gradio 5 默认主题更为柔和。gr.themes.Citrus()
- "citrus"
主题使用黄色作为主色,突出显示获得焦点的表单元素,并在点击按钮时包含有趣的 3D 效果。gr.themes.Monochrome()
- "monochrome"
主题使用黑色作为主色和白色作为次色,并使用衬线字体,呈现出黑白报纸的外观。gr.themes.Soft()
- "soft"
主题使用紫色作为主色和白色作为次色。它还增加了按钮和表单元素周围的边框圆角,并突出显示标签。gr.themes.Glass()
- "glass"
主题具有蓝色主色和半透明灰色次色。该主题还使用垂直渐变来创建玻璃效果。gr.themes.Ocean()
- "ocean"
主题具有蓝绿色主色和灰色次色。该主题还使用水平渐变,特别是用于按钮和某些表单元素。这些主题中的每一个都为数百个 CSS 变量设置了值。你可以使用预构建主题作为自定义主题的起点,或者从头开始创建自己的主题。让我们来看看每种方法。
构建主题最简单的方法是使用主题构建器。要在本地启动主题构建器,请运行以下代码:
import gradio as gr
gr.themes.builder()
你可以使用上方 Spaces 上运行的主题构建器,尽管在本地通过 gr.themes.builder()
启动时它运行得更快。
当你编辑主题构建器中的值时,应用会实时预览更新。你可以下载生成你所创建主题的代码,以便在任何 Gradio 应用中使用。
本指南的其余部分将介绍如何通过编程方式构建主题。
尽管每个主题都有数百个 CSS 变量,但其中大多数变量的值都来自 8 个核心变量,这些变量可以通过每个预构建主题的构造函数进行设置。修改这 8 个参数可以让你快速更改应用的视觉外观和风格。
前 3 个构造函数参数设置主题的颜色,它们是 gradio.themes.Color
对象。在内部,这些 Color 对象包含单一色调调色板的亮度值,范围从 50、100、200...、800、900、950。其他 CSS 变量都派生自这 3 种颜色。
这 3 个颜色构造函数参数是:
primary_hue
:这是主题中吸引注意力的颜色。在默认主题中,它设置为 gradio.themes.colors.orange
。secondary_hue
:这是主题中用于次要元素的颜色。在默认主题中,它设置为 gradio.themes.colors.blue
。neutral_hue
:这是主题中用于文本和其他中性元素的颜色。在默认主题中,它设置为 gradio.themes.colors.gray
。你可以使用它们的字符串快捷方式修改这些值,例如:
with gr.Blocks(theme=gr.themes.Default(primary_hue="red", secondary_hue="pink")) as demo:
...
或者你可以直接使用 Color
对象,像这样:
with gr.Blocks(theme=gr.themes.Default(primary_hue=gr.themes.colors.red, secondary_hue=gr.themes.colors.pink)) as demo:
...
预定义的颜色有:
板岩色
灰色
锌色
中性色
石色
红色
橙色
琥珀色
黄色
酸橙色
绿色
翡翠色
青色
青绿色
天蓝色
蓝色
靛蓝色
紫罗兰色
紫色
紫红色
粉色
玫瑰色
你也可以创建自己的自定义 Color
对象并传入。
接下来的 3 个构造函数参数设置主题的尺寸,它们是 gradio.themes.Size
对象。在内部,这些 Size 对象包含从 xxs
到 xxl
的像素尺寸值。其他 CSS 变量都派生自这 3 种尺寸。
spacing_size
:这设置了元素内部的填充和元素之间的间距。在默认主题中,它设置为 gradio.themes.sizes.spacing_md
。radius_size
:这设置了元素圆角的圆度。在默认主题中,它设置为 gradio.themes.sizes.radius_md
。text_size
:这设置了文本的字体大小。在默认主题中,它设置为 gradio.themes.sizes.text_md
。你可以使用它们的字符串快捷方式修改这些值,例如:
with gr.Blocks(theme=gr.themes.Default(spacing_size="sm", radius_size="none")) as demo:
...
或者你可以直接使用 Size
对象,像这样:
with gr.Blocks(theme=gr.themes.Default(spacing_size=gr.themes.sizes.spacing_sm, radius_size=gr.themes.sizes.radius_none)) as demo:
...
预定义的尺寸对象有:
radius_none
radius_sm
radius_md
radius_lg
spacing_sm
spacing_md
spacing_lg
text_sm
text_md
text_lg
你也可以创建自己的自定义 Size
对象并传入。
最后 2 个构造函数参数设置主题的字体。你可以为每个参数传递一个字体列表来指定回退字体。如果你提供一个字符串,它将被加载为系统字体。如果你提供一个 gradio.themes.GoogleFont
,字体将从 Google Fonts 加载。
font
:这设置了主题的主字体。在默认主题中,它设置为 gradio.themes.GoogleFont("IBM Plex Sans")
。font_mono
:这设置了主题的等宽字体。在默认主题中,它设置为 gradio.themes.GoogleFont("IBM Plex Mono")
。你可以修改这些值,如下所示:
with gr.Blocks(theme=gr.themes.Default(font=[gr.themes.GoogleFont("Inconsolata"), "Arial", "sans-serif"])) as demo:
...
.set()
扩展主题你也可以在主题加载后修改 CSS 变量的值。为此,使用主题对象的 .set()
方法来访问 CSS 变量。例如:
theme = gr.themes.Default(primary_hue="blue").set(
loader_color="#FF0000",
slider_color="#FF0000",
)
with gr.Blocks(theme=theme) as demo:
...
在上面的示例中,我们将 loader_color
和 slider_color
变量设置为 #FF0000
,尽管整体 primary_color
使用的是蓝色调色板。你可以通过这种方式设置主题中定义的任何 CSS 变量。
你的 IDE 类型提示应该能帮助你导航这些变量。由于 CSS 变量很多,我们来看看这些变量是如何命名和组织的。
CSS 变量名可能会很长,例如 button_primary_background_fill_hover_dark
!但它们遵循一种通用的命名约定,这使得它们易于理解其作用并方便查找你所需的变量。变量名由下划线分隔,包含以下部分:
button
(按钮)、slider
(滑块)或 block
(块)。button_primary
(主按钮)或 block_label
(块标签)。button_primary_background_fill
(主按钮背景填充)或 block_label_border_width
(块标签边框宽度)。button_primary_background_fill_hover
(主按钮背景填充悬停)。_dark
。例如,input_border_color_focus_dark
(输入边框颜色焦点深色)。当然,许多 CSS 变量名比这更短,例如 table_border_color
(表格边框颜色)或 input_shadow
(输入阴影)。
尽管有数百个 CSS 变量,但它们不必都具有独立的值。它们通过引用一组核心变量和相互引用来获取值。这使得我们只需修改少数变量即可更改整个主题的视觉外观和风格,同时也能更精细地控制我们可能希望修改的单个元素。
要引用核心构造函数变量之一,请在变量名前加上星号。要引用核心颜色,请使用 *primary_
、*secondary_
或 *neutral_
前缀,后跟亮度值。例如:
theme = gr.themes.Default(primary_hue="blue").set(
button_primary_background_fill="*primary_200",
button_primary_background_fill_hover="*primary_300",
)
在上面的示例中,我们将 button_primary_background_fill
和 button_primary_background_fill_hover
变量分别设置为 *primary_200
和 *primary_300
。这些变量将分别设置为蓝色主色调色板的 200 和 300 亮度值。
同样,要引用核心尺寸,请使用 *spacing_
、*radius_
或 *text_
前缀,后跟尺寸值。例如:
theme = gr.themes.Default(radius_size="md").set(
button_primary_border_radius="*radius_xl",
)
在上面的示例中,我们将 button_primary_border_radius
变量设置为 *radius_xl
。此变量将设置为中等半径尺寸范围的 xl
设置。
变量也可以相互引用。例如,请看下面的示例:
theme = gr.themes.Default().set(
button_primary_background_fill="#FF0000",
button_primary_background_fill_hover="#FF0000",
button_primary_border="#FF0000",
)
将这些值设置为相同颜色有点繁琐。相反,我们可以使用 *
前缀,在 button_primary_background_fill_hover
和 button_primary_border
变量中引用 button_primary_background_fill
变量。
theme = gr.themes.Default().set(
button_primary_background_fill="#FF0000",
button_primary_background_fill_hover="*button_primary_background_fill",
button_primary_border="*button_primary_background_fill",
)
现在,如果我们更改 button_primary_background_fill
变量,button_primary_background_fill_hover
和 button_primary_border
变量也会自动更新。
如果你打算分享你的主题,这会特别有用——它使得修改主题变得容易,而无需更改每个变量。
请注意,深色模式变量会自动相互引用。例如:
theme = gr.themes.Default().set(
button_primary_background_fill="#FF0000",
button_primary_background_fill_dark="#AAAAAA",
button_primary_border="*button_primary_background_fill",
button_primary_border_dark="*button_primary_background_fill_dark",
)
button_primary_border_dark
将从 button_primary_background_fill_dark
获取其值,因为深色模式总是从变量的深色版本中获取。
假设你想从头开始创建一个主题!我们将一步步进行——你也可以参考 Gradio 源代码仓库中的预构建主题源文件——这是 Monochrome 主题的源文件。
我们的新主题类将继承自 gradio.themes.Base
,这是一个设置了许多方便的默认值的主题。让我们创建一个简单的演示,创建一个名为 Seafoam 的虚拟主题,并制作一个使用它的简单应用。
import gradio as gr
from gradio.themes.base import Base
import time
class Seafoam(Base):
pass
seafoam = Seafoam()
with gr.Blocks(theme=seafoam) as demo:
textbox = gr.Textbox(label="Name")
slider = gr.Slider(label="Count", minimum=0, maximum=100, step=1)
with gr.Row():
button = gr.Button("Submit", variant="primary")
clear = gr.Button("Clear")
output = gr.Textbox(label="Output")
def repeat(name, count):
time.sleep(3)
return name * count
button.click(repeat, [textbox, slider], output)
demo.launch()
Base 主题非常精简,使用 gr.themes.Blue
作为其主色——你会注意到主按钮和加载动画因此都是蓝色的。让我们改变应用的默认核心参数。我们将覆盖构造函数并为核心构造函数参数传递新的默认值。
我们将使用 gr.themes.Emerald
作为主色,并将次要色调和中性色调设置为 gr.themes.Blue
。我们将使用 text_lg
使文本更大。我们将使用从 Google Fonts 加载的 Quicksand
作为默认字体。
from __future__ import annotations
from typing import Iterable
import gradio as gr
from gradio.themes.base import Base
from gradio.themes.utils import colors, fonts, sizes
import time
class Seafoam(Base):
def __init__(
self,
*,
primary_hue: colors.Color | str = colors.emerald,
secondary_hue: colors.Color | str = colors.blue,
neutral_hue: colors.Color | str = colors.gray,
spacing_size: sizes.Size | str = sizes.spacing_md,
radius_size: sizes.Size | str = sizes.radius_md,
text_size: sizes.Size | str = sizes.text_lg,
font: fonts.Font
| str
| Iterable[fonts.Font | str] = (
fonts.GoogleFont("Quicksand"),
"ui-sans-serif",
"sans-serif",
),
font_mono: fonts.Font
| str
| Iterable[fonts.Font | str] = (
fonts.GoogleFont("IBM Plex Mono"),
"ui-monospace",
"monospace",
),
):
super().__init__(
primary_hue=primary_hue,
secondary_hue=secondary_hue,
neutral_hue=neutral_hue,
spacing_size=spacing_size,
radius_size=radius_size,
text_size=text_size,
font=font,
font_mono=font_mono,
)
seafoam = Seafoam()
with gr.Blocks(theme=seafoam) as demo:
textbox = gr.Textbox(label="Name")
slider = gr.Slider(label="Count", minimum=0, maximum=100, step=1)
with gr.Row():
button = gr.Button("Submit", variant="primary")
clear = gr.Button("Clear")
output = gr.Textbox(label="Output")
def repeat(name, count):
time.sleep(3)
return name * count
button.click(repeat, [textbox, slider], output)
demo.launch()
看到主按钮和加载动画现在变成绿色了吗?这些 CSS 变量与 primary_hue
变量相关联。
让我们更直接地修改主题。我们将调用 set()
方法来显式覆盖 CSS 变量值。我们可以使用任何 CSS 逻辑,并使用 *
前缀引用我们的核心构造函数参数。
from __future__ import annotations
from typing import Iterable
import gradio as gr
from gradio.themes.base import Base
from gradio.themes.utils import colors, fonts, sizes
import time
class Seafoam(Base):
def __init__(
self,
*,
primary_hue: colors.Color | str = colors.emerald,
secondary_hue: colors.Color | str = colors.blue,
neutral_hue: colors.Color | str = colors.blue,
spacing_size: sizes.Size | str = sizes.spacing_md,
radius_size: sizes.Size | str = sizes.radius_md,
text_size: sizes.Size | str = sizes.text_lg,
font: fonts.Font
| str
| Iterable[fonts.Font | str] = (
fonts.GoogleFont("Quicksand"),
"ui-sans-serif",
"sans-serif",
),
font_mono: fonts.Font
| str
| Iterable[fonts.Font | str] = (
fonts.GoogleFont("IBM Plex Mono"),
"ui-monospace",
"monospace",
),
):
super().__init__(
primary_hue=primary_hue,
secondary_hue=secondary_hue,
neutral_hue=neutral_hue,
spacing_size=spacing_size,
radius_size=radius_size,
text_size=text_size,
font=font,
font_mono=font_mono,
)
super().set(
body_background_fill="repeating-linear-gradient(45deg, *primary_200, *primary_200 10px, *primary_50 10px, *primary_50 20px)",
body_background_fill_dark="repeating-linear-gradient(45deg, *primary_800, *primary_800 10px, *primary_900 10px, *primary_900 20px)",
button_primary_background_fill="linear-gradient(90deg, *primary_300, *secondary_400)",
button_primary_background_fill_hover="linear-gradient(90deg, *primary_200, *secondary_300)",
button_primary_text_color="white",
button_primary_background_fill_dark="linear-gradient(90deg, *primary_600, *secondary_800)",
slider_color="*secondary_300",
slider_color_dark="*secondary_600",
block_title_text_weight="600",
block_border_width="3px",
block_shadow="*shadow_drop_lg",
button_primary_shadow="*shadow_drop_lg",
button_large_padding="32px",
)
seafoam = Seafoam()
with gr.Blocks(theme=seafoam) as demo:
textbox = gr.Textbox(label="Name")
slider = gr.Slider(label="Count", minimum=0, maximum=100, step=1)
with gr.Row():
button = gr.Button("Submit", variant="primary")
clear = gr.Button("Clear")
output = gr.Textbox(label="Output")
def repeat(name, count):
time.sleep(3)
return name * count
button.click(repeat, [textbox, slider], output)
demo.launch()
看看我们的主题现在多么有趣!只需更改几个变量,我们的主题就焕然一新。
你可能会发现查看其他预构建主题的源代码很有帮助,以了解它们如何修改基础主题。你还可以使用浏览器的检查器(Inspector)来选择 UI 元素,并在样式面板中查看正在使用的 CSS 变量。
创建主题后,你可以将其上传到 HuggingFace Hub,让其他人查看、使用和在此基础上构建!
有两种上传主题的方法:通过主题类实例或命令行。我们将以之前创建的 seafoam
主题为例,介绍这两种方法。
每个主题实例都有一个名为 push_to_hub
的方法,我们可以用它将主题上传到 HuggingFace hub。
seafoam.push_to_hub(repo_name="seafoam",
version="0.0.1",
hf_token="<token>")
首先将主题保存到磁盘
seafoam.dump(filename="seafoam.json")
然后使用 upload_theme
命令
upload_theme\
"seafoam.json"\
"seafoam"\
--version "0.0.1"\
--hf_token "<token>"
要上传主题,你必须拥有一个 HuggingFace 账户,并将你的访问令牌作为 hf_token
参数传入。但是,如果你通过HuggingFace 命令行登录(随 gradio
一同安装),则可以省略 hf_token
参数。
version
参数允许你为主题指定一个有效的语义版本字符串。这样,你的用户就能指定他们想在应用中使用你的主题的哪个版本。这也允许你发布主题更新,而无需担心改变之前创建的应用的外观。version
参数是可选的。如果省略,将自动应用下一个补丁版本。
通过调用 push_to_hub
或 upload_theme
,主题资源将存储在 HuggingFace space 中。
例如,平静海沫主题的预览在此处:平静海沫预览。
主题库展示了所有公共 Gradio 主题。发布你的主题后,它会在几分钟内自动显示在主题库中。
你可以根据空间上的点赞数、从最新到最旧创建的顺序对主题进行排序,并可在浅色和深色模式之间切换主题。
要使用 Hub 中的主题,请在 ThemeClass
上使用 from_hub
方法并将其传递给你的应用
my_theme = gr.Theme.from_hub("gradio/seafoam")
with gr.Blocks(theme=my_theme) as demo:
....
你也可以将主题字符串直接传递给 Blocks
或 Interface
(gr.Blocks(theme="gradio/seafoam")
)
你可以通过使用语义版本表达式将你的应用固定到上游主题版本。
例如,以下代码将确保我们从 seafoam
仓库加载的主题版本介于 0.0.1
和 0.1.0
之间。
with gr.Blocks(theme="gradio/seafoam@>=0.0.1,<0.1.0") as demo:
....
尽情创建你自己的主题吧!如果你创建了一个引以为傲的主题,请将其上传到 Hub,与世界分享!如果你在 Twitter 上标记我们,我们可以为你的主题进行宣传!