Intermediate
Gradio Blocks
gr.Blocks() gives you full control over layout, event handling, and component interactions. Build multi-step workflows, tabbed interfaces, and complex UIs that go beyond what Interface offers.
Basic Blocks Layout
Python
import gradio as gr with gr.Blocks() as demo: gr.Markdown("# My Custom App") with gr.Row(): with gr.Column(scale=2): input_text = gr.Textbox(label="Input", lines=5) btn = gr.Button("Generate", variant="primary") with gr.Column(scale=3): output_text = gr.Textbox(label="Output", lines=5) btn.click(fn=my_function, inputs=input_text, outputs=output_text) demo.launch()
Layout Components
gr.Row()
Place components side by side horizontally. Use equal_height=True to align components.
gr.Column()
Stack components vertically. Use scale to control relative widths within a Row.
gr.Tab()
Create tabbed interfaces for organizing different sections of your app.
gr.Accordion()
Collapsible sections for advanced options that users can expand when needed.
Tabbed Interface
Python
with gr.Blocks() as demo: with gr.Tabs(): with gr.Tab("Text Generation"): text_input = gr.Textbox(label="Prompt") text_output = gr.Textbox(label="Response") text_btn = gr.Button("Generate") with gr.Tab("Image Analysis"): image_input = gr.Image(type="pil") image_output = gr.Label() image_btn = gr.Button("Classify") text_btn.click(generate_text, text_input, text_output) image_btn.click(classify_image, image_input, image_output)
Event Handling
Blocks supports multiple event types beyond simple button clicks:
Python
with gr.Blocks() as demo: text = gr.Textbox(label="Input") output = gr.Textbox(label="Output") btn = gr.Button("Submit") # Button click btn.click(fn=process, inputs=text, outputs=output) # Real-time as user types text.change(fn=live_preview, inputs=text, outputs=output) # On Enter key text.submit(fn=process, inputs=text, outputs=output) # Chained events btn.click(fn=step1, inputs=text, outputs=output) \ .then(fn=step2, inputs=output, outputs=output)
State Management
Python
with gr.Blocks() as demo: # Per-session state (each user gets their own) history = gr.State([]) chatbot = gr.Chatbot() msg = gr.Textbox(label="Message") def respond(message, chat_history): response = generate_response(message) chat_history.append((message, response)) return "", chat_history msg.submit(respond, [msg, chatbot], [msg, chatbot])
Theming
Python
# Built-in themes demo = gr.Blocks(theme=gr.themes.Soft()) demo = gr.Blocks(theme=gr.themes.Monochrome()) demo = gr.Blocks(theme=gr.themes.Glass()) # Custom theme my_theme = gr.themes.Soft( primary_hue="indigo", secondary_hue="blue", font=[gr.themes.GoogleFont("Inter"), "sans-serif"], ) demo = gr.Blocks(theme=my_theme)
Blocks vs Interface: Use Interface for quick single-function demos. Use Blocks when you need custom layouts, multiple event handlers, state management, or multi-step workflows.
What's Next?
Now that you can build custom UIs, let's learn how to deploy your Gradio apps — from instant sharing to production deployment on Hugging Face Spaces.
Lilly Tech Systems