> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/gradio-app/gradio/llms.txt
> Use this file to discover all available pages before exploring further.

# Events

> Learn how to use Gradio's event system to create interactive applications

Events are the mechanism that makes Gradio applications interactive. An event listener connects a component interaction (like a button click) to a Python function, allowing you to respond to user actions in real-time.

## What are events?

In Gradio, events are triggered by user interactions with components. When an event occurs, Gradio can:

1. Run a Python function
2. Pass component values as inputs to that function
3. Update other components with the function's outputs

This creates the interactive loop that powers Gradio applications.

## Basic event structure

Every event listener follows this pattern:

```python theme={null}
component.event_name(
    fn=function_to_run,
    inputs=[input_components],
    outputs=[output_components]
)
```

For example:

```python theme={null}
import gradio as gr

def greet(name):
    return f"Hello, {name}!"

with gr.Blocks() as demo:
    name_input = gr.Textbox(label="Name")
    output = gr.Textbox(label="Greeting")
    button = gr.Button("Greet")
    
    button.click(fn=greet, inputs=name_input, outputs=output)
```

## Common event types

### Click events

Triggered when a button is clicked:

```python theme={null}
import gradio as gr

def process():
    return "Button clicked!"

with gr.Blocks() as demo:
    output = gr.Textbox()
    button = gr.Button("Click me")
    
    button.click(fn=process, inputs=None, outputs=output)
```

### Change events

Triggered when a component's value changes:

```python theme={null}
import gradio as gr

def update(text):
    return text.upper()

with gr.Blocks() as demo:
    inp = gr.Textbox(label="Type here")
    out = gr.Textbox(label="Uppercase")
    
    inp.change(fn=update, inputs=inp, outputs=out)
```

<Note>
  The `.change()` event fires both when users type AND when the value is updated programmatically. Use `.input()` for events triggered only by user input.
</Note>

### Submit events

Triggered when users press Enter in a textbox:

```python theme={null}
import gradio as gr

def process(text):
    return f"You submitted: {text}"

with gr.Blocks() as demo:
    inp = gr.Textbox(label="Press Enter to submit")
    out = gr.Textbox()
    
    inp.submit(fn=process, inputs=inp, outputs=out)
```

### Input events

Triggered only by direct user input (not programmatic updates):

```python theme={null}
import gradio as gr

def count_chars(text):
    return f"Character count: {len(text)}"

with gr.Blocks() as demo:
    inp = gr.Textbox(label="Type here")
    out = gr.Textbox(label="Count")
    
    inp.input(fn=count_chars, inputs=inp, outputs=out)
```

### Select events

Triggered when selecting items in components like Gallery, Dataframe, or highlighted text:

```python theme={null}
import gradio as gr

def show_selection(evt: gr.SelectData):
    return f"You selected: {evt.value} at index {evt.index}"

with gr.Blocks() as demo:
    gallery = gr.Gallery([("cat.jpg", "Cat"), ("dog.jpg", "Dog")])
    output = gr.Textbox()
    
    gallery.select(fn=show_selection, inputs=None, outputs=output)
```

## Event data objects

Some events provide additional context through event data classes:

### SelectData

Contains information about selected items:

```python theme={null}
import gradio as gr

def on_select(evt: gr.SelectData):
    return f"Index: {evt.index}, Value: {evt.value}"

with gr.Blocks() as demo:
    dataframe = gr.Dataframe([[1, 2], [3, 4]])
    output = gr.Textbox()
    
    dataframe.select(fn=on_select, inputs=None, outputs=output)
```

**SelectData attributes:**

* `evt.index` - Index of selected item (or tuple for 2D components)
* `evt.value` - Value of selected item
* `evt.selected` - True if selected, False if deselected
* `evt.target` - The component that triggered the event

### LikeData

For chatbot like/dislike events:

```python theme={null}
import gradio as gr

def handle_like(evt: gr.LikeData):
    action = "liked" if evt.liked else "disliked"
    return f"You {action} message {evt.index}: {evt.value}"

with gr.Blocks() as demo:
    chatbot = gr.Chatbot([["Hello", "Hi there!"]])
    output = gr.Textbox()
    
    chatbot.like(fn=handle_like, inputs=None, outputs=output)
```

**LikeData attributes:**

* `evt.index` - Index of the liked/disliked message
* `evt.value` - Content of the message
* `evt.liked` - True if liked, False if disliked

### KeyUpData

For key press events:

```python theme={null}
import gradio as gr

def on_key(evt: gr.KeyUpData):
    return f"Key: {evt.key}, Input: {evt.input_value}"

with gr.Blocks() as demo:
    dropdown = gr.Dropdown(["a", "b", "c"], allow_custom_value=True)
    output = gr.JSON()
    
    dropdown.key_up(fn=on_key, inputs=None, outputs=output)
```

## Event chaining

Chain events together using `.then()`, `.success()`, and `.failure()`:

### Sequential execution with .then()

```python theme={null}
import gradio as gr

def step1(text):
    return text.upper()

def step2(text):
    return text + "!!!"

with gr.Blocks() as demo:
    inp = gr.Textbox()
    mid = gr.Textbox()
    out = gr.Textbox()
    btn = gr.Button("Process")
    
    btn.click(fn=step1, inputs=inp, outputs=mid).then(
        fn=step2, inputs=mid, outputs=out
    )
```

### Success and failure handlers

```python theme={null}
import gradio as gr

def risky_operation(x):
    if x < 0:
        raise ValueError("Negative numbers not allowed!")
    return x * 2

def on_success():
    return "Operation completed successfully!"

def on_failure():
    return "Operation failed!"

with gr.Blocks() as demo:
    inp = gr.Number()
    out = gr.Number()
    status = gr.Textbox()
    btn = gr.Button("Calculate")
    
    btn.click(
        fn=risky_operation, inputs=inp, outputs=out
    ).success(
        fn=on_success, inputs=None, outputs=status
    ).failure(
        fn=on_failure, inputs=None, outputs=status
    )
```

## The gr.on() function

Use `gr.on()` to trigger a function from multiple events:

```python theme={null}
import gradio as gr

def process(text):
    return text.upper()

with gr.Blocks() as demo:
    textbox = gr.Textbox()
    button = gr.Button("Submit")
    output = gr.Textbox()
    
    # Same function triggered by both events
    gr.on(
        triggers=[button.click, textbox.submit],
        fn=process,
        inputs=textbox,
        outputs=output
    )
```

This is more efficient than setting up separate listeners - it creates only one API endpoint.

## Event parameters

### Controlling behavior

```python theme={null}
button.click(
    fn=process,
    inputs=inp,
    outputs=out,
    # Control queueing
    queue=True,  # Use the queue (default)
    concurrency_limit=3,  # Max 3 simultaneous executions
    
    # Control trigger behavior
    trigger_mode="once",  # "once", "multiple", or "always_last"
    
    # Display options
    show_progress="full",  # "full", "minimal", or "hidden"
    scroll_to_output=True,  # Auto-scroll to output
    
    # API options
    api_name="process_text",  # Custom endpoint name
    api_visibility="public"  # "public", "private", or "undocumented"
)
```

### Trigger modes

* **"once"** (default): Prevents new submissions while one is running
* **"multiple"**: Allows unlimited simultaneous submissions
* **"always\_last"**: Queues the most recent submission, cancelling intermediate ones

```python theme={null}
import gradio as gr
import time

def slow_process(x):
    time.sleep(3)
    return x * 2

with gr.Blocks() as demo:
    inp = gr.Number()
    out = gr.Number()
    btn = gr.Button("Process")
    
    btn.click(
        fn=slow_process,
        inputs=inp,
        outputs=out,
        trigger_mode="always_last"  # Always process the latest value
    )
```

## Cancelling events

Cancel running events when a new event starts:

```python theme={null}
import gradio as gr
import time

def long_process(x):
    for i in range(10):
        time.sleep(1)
        yield f"Step {i}: {x}"

with gr.Blocks() as demo:
    inp = gr.Textbox()
    out = gr.Textbox()
    start_btn = gr.Button("Start")
    stop_btn = gr.Button("Stop")
    
    click_event = start_btn.click(fn=long_process, inputs=inp, outputs=out)
    
    # Clicking stop cancels the running event
    stop_btn.click(fn=None, inputs=None, outputs=None, cancels=[click_event])
```

## Preprocessing and postprocessing

Control how data flows through events:

```python theme={null}
button.click(
    fn=process,
    inputs=image,
    outputs=result,
    preprocess=True,   # Convert image to expected format before fn
    postprocess=True   # Convert fn output for display
)
```

Set to `False` to work with raw component data:

```python theme={null}
# Get base64 image string instead of PIL Image
button.click(
    fn=process_base64,
    inputs=image,
    outputs=result,
    preprocess=False  # Skip conversion to PIL
)
```

## Generator functions

Use generator functions for streaming outputs:

```python theme={null}
import gradio as gr
import time

def stream_data(text):
    for word in text.split():
        time.sleep(0.5)
        yield word

with gr.Blocks() as demo:
    inp = gr.Textbox()
    out = gr.Textbox()
    btn = gr.Button("Stream")
    
    btn.click(fn=stream_data, inputs=inp, outputs=out)
```

Outputs update in real-time as the generator yields values.

## JavaScript events

Run JavaScript before or after Python functions:

```python theme={null}
import gradio as gr

with gr.Blocks() as demo:
    inp = gr.Textbox()
    out = gr.Textbox()
    btn = gr.Button("Submit")
    
    btn.click(
        fn=lambda x: x.upper(),
        inputs=inp,
        outputs=out,
        js="() => alert('Processing started!')"
    )
```

## Load events

Run functions when the page loads:

```python theme={null}
import gradio as gr
import datetime

def get_time():
    return f"Page loaded at {datetime.datetime.now()}"

with gr.Blocks() as demo:
    output = gr.Textbox()
    
    demo.load(fn=get_time, inputs=None, outputs=output)
```

## Component-specific events

Different components support different events:

* **Button**: `click`
* **Textbox**: `change`, `input`, `submit`, `focus`, `blur`
* **Slider**: `change`, `release`
* **File**: `upload`, `delete`, `download`, `change`
* **Image**: `select`, `change`, `clear`, `upload`
* **Chatbot**: `change`, `select`, `like`, `retry`, `undo`, `clear`
* **Gallery**: `select`, `change`
* **Dataframe**: `select`, `change`, `input`

Check each component's documentation for its supported events.

## Event best practices

<Tip>
  **Performance**: Use `gr.on()` instead of multiple individual listeners when the same function responds to multiple events.
</Tip>

<Tip>
  **Responsiveness**: Use `show_progress="minimal"` or `"hidden"` for fast operations to reduce visual clutter.
</Tip>

<Warning>
  **State isolation**: Remember that State components are session-specific. Different users don't share state values.
</Warning>

<Note>
  **Queueing**: Long-running or generator functions require the queue to be enabled (it's enabled by default).
</Note>

## See also

* [Interface](/concepts/interface) - High-level event handling
* [Blocks](/concepts/blocks) - Advanced event patterns
* [Components](/concepts/components) - Which events each component supports
* [State](/concepts/state) - Managing persistent data across events


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.