Blocks 是 Gradio 库中的一个用来自定义构建交互式 web app 的模块。它相较于 Interface 而言,更加底层,能够用来构建更复杂的应用。ChatInterface 可用来便捷构建聊天机器人交互页面。
1. 基本使用
import gradio as gr
def test():
with gr.Blocks(title='我的应用', theme=gr.themes.Ocean()) as app:
# 创建所需控件
num1 = gr.Number()
num2 = gr.Number()
button = gr.Button('提交')
# 绑定点击事件
# 方式一
def response(num):
return num + 100
button.click(fn=response, inputs=num1, outputs=num2)
# 方式二
# @button.click(inputs=num1, outputs=num2)
# def response(num):
# return num + 100
app.launch()
if __name__ == '__main__':
test()
2. 事件处理
如何将多个事件便捷绑定到同一个处理函数上,以及如何连续处理事件。
import gradio as gr
# 1. gr.on 多个事件绑定到同一个函数
def test01():
with gr.Blocks() as app:
num1 = gr.Number()
num2 = gr.Number()
button = gr.Button()
# 将多个事件绑定到同一个事件处理函数上
def my_submit(num):
return num + 100
# 1. 分别绑定
num1.submit(my_submit, inputs=num1, outputs=num2)
button.click(my_submit, inputs=num1, outputs=num2)
# 2. 使用 gr.on
# gr.on(triggers=[button.click, num1.submit], fn=my_submit, inputs=num1, outputs=num2)
@gr.on(triggers=[button.click, num1.submit], inputs=num1, outputs=num2)
def my_submit(num):
return num + 100
app.launch()
# 2. 连续事件 then 和 success
def test02():
with gr.Blocks() as app:
num1 = gr.Number()
num2 = gr.Number(interactive=True)
num3 = gr.Number(interactive=True)
btn1 = gr.Button('提交')
btn2 = gr.Button('提交')
# then:无论上一个事件是否抛出异常,下一个事件都会执行
def then_submit1(num):
# raise gr.Error('错误发生')
return num + 10
def then_submit2(num):
return num + 100
btn1.click(fn=then_submit1, inputs=num1, outputs=num2).then(then_submit2, inputs=num2, outputs=num3)
# success:只有上一个事件没有抛出异常,下一个事件才会执行
def success_submit1(num):
# raise gr.Error('错误发生')
return num + 10
def success_submit2(num):
return num + 100
btn2.click(fn=success_submit1, inputs=num1, outputs=num2).success(fn=success_submit2, inputs=num2, outputs=num3)
app.launch()
if __name__ == '__main__':
test02()
3. 布局控制
主要四种常见布局:gradio.Row、gradio.Column、gradio.Tab、gradio.Accordion
import gradio as gr
def test():
with gr.Blocks(fill_width=True, fill_height=True) as app:
with gr.Row():
# 控件在一行水平排列
with gr.Row():
# scale 调整控件占比
gr.Textbox(label='text1', scale=1)
gr.Textbox(label='text2', scale=2)
gr.Image('https://mengbaoliang.cn/wp-content/uploads/2023/12/a40e7875913e8d5.png', scale=3)
# 控件在一列垂直排列
with gr.Column():
gr.TextArea(label='area1')
gr.TextArea(label='area2')
with gr.Tab('标签页1'):
with gr.Row():
gr.Textbox(label='text1')
gr.Textbox(label='text2')
with gr.Tab('标签页2'):
with gr.Column():
gr.TextArea(label='area1')
gr.TextArea(label='area2')
with gr.Accordion('折叠/展开', open=False):
with gr.Column():
gr.TextArea(label='area1')
gr.TextArea(label='area2')
app.launch()
if __name__ == '__main__':
test()
4. 动态渲染
import gradio as gr
# 1. 通过输入数字创建控件
def test01():
with gr.Blocks() as app:
gr.Markdown('# 动态创建控件')
numnber = gr.Number(label='控件数量')
@gr.render(inputs=numnber, triggers=[numnber.submit,])
def add_components(number):
for i in range(number):
gr.Number()
app.launch()
# 2. 通过点击按钮创建控件
def test02():
with gr.Blocks() as app:
gr.Markdown('# 动态创建控件')
with gr.Row():
state = gr.State(0)
btn1 = gr.Button('增加')
btn2 = gr.Button('减少')
# 改变 state 的值
btn1.click(lambda x : x + 1, state, state)
btn2.click(lambda x : x - 1, state, state)
@gr.render(inputs=state, triggers=[state.change,])
def change_components(number):
for i in range(number):
with gr.Row():
num1 = gr.Number(key=f'in{i}')
num2 = gr.Number(key=f'out{i}')
num1.submit(fn=lambda x : x + 100, inputs=num1, outputs=num2)
app.launch()
if __name__ == '__main__':
test02()
5. 修改属性
import gradio as gr
def test():
with gr.Blocks() as app:
choice = gr.Radio(choices=['1', '3', '5', '7'])
output = gr.Textbox(label="输出")
@choice.change(inputs=choice, outputs=output)
def process_function(value):
if value == '1':
return gr.update(lines=1, value="一行")
if value == '3':
return gr.update(lines=3, value="三行")
if value == '5':
return gr.update(lines=5, value="五行")
if value == '7':
return gr.update(lines=7, value="七行")
app.launch()
if __name__ == '__main__':
test()

冀公网安备13050302001966号