Skip to content

input or change event of Dataframe will not be triggered when the focus doesn't change #11612

@Yb2S3Man

Description

@Yb2S3Man

Describe the bug

The input and change event will only happens when the focus has been changed from the dataframe to other control.
For example:

  • Click the dataframe, and input any characters into the editable cells, such as 'A' in cell[0,0], 'B' in cell[1,1], 'C' in cell[2,2]
  • If we input those three characters without switch the focus, only 'C' will trigger the input or change event, and 'A', 'B' will disappear, that's not what we expect
  • If we input 'A' in cell[0,0], then switch the focus out of the dataframe, the input and change event will be triggered, then we follow this same actions for 'B', 'C', then the input or change event will be triggered again and again, that's we expect

Have you searched existing issues? 🔎

  • I have searched and found no existing issues

Reproduction

#!/usr/bin/env python
# -*- coding:UTF-8 -*-
import gradio as gr
from pathlib import Path
from dataclasses import dataclass
import getpass
import pandas as pd
import re
import math
DTYPE_DICT = {'row_num': int,
              'name': str,
              'gender': str,
              'age': str,
              'country': str,
              'phone': str,
              }
CSV_HEADER_LIST = list(DTYPE_DICT.keys())
ROWS_PER_PAGE = 10
USER_SESSIONS = {}
@dataclass
class UserInfo:
    """Class representing a user"""
    src_full_path_name: Path = None
    origin_df: pd.DataFrame = None
    display_df: pd.DataFrame = None
    audio_base_path: Path = None
    current_page: int = 1
    total_pages: int = 1
    rows_per_page: int = ROWS_PER_PAGE
CURRENT_SESSION = None
username = getpass.getuser()
if username in USER_SESSIONS:
    CURRENT_SESSION = USER_SESSIONS.get(username)
else:
    USER_SESSIONS[username] = UserInfo()
    CURRENT_SESSION = USER_SESSIONS[username]

def load_file():
    src_file = ......
    df = pd.read_excel(src_file, dtype=DTYPE_DICT, sheet_name=0, engine='openpyxl', header=0)
    CURRENT_SESSION.src_full_path_name = str(src_file)
    CURRENT_SESSION.current_page = 1
    CURRENT_SESSION.total_pages = math.ceil(len(df) / ROWS_PER_PAGE)
    CURRENT_SESSION.rows_per_page = ROWS_PER_PAGE
    original_df = df.copy()
    CURRENT_SESSION.origin_df = original_df
    df['audio file'] = df['audio file'].apply(__format_audio_file_column__)
    CURRENT_SESSION.display_df = df.iloc[:, :len(CSV_HEADER_LIST)]
    df = df.iloc[0:ROWS_PER_PAGE, :len(CSV_HEADER_LIST)]
    return gr.Dataframe(value=df, headers=CSV_HEADER_LIST, col_count=len(CSV_HEADER_LIST),
                        datatype='html', wrap=True, row_count=[ROWS_PER_PAGE, 'fixed'], show_search='search',
                        show_fullscreen_button=True, line_breaks=True,
                        interactive=True, max_height=1920,
                        render=True, visible=True)

def table_change(table_content):
    if table_content is None or table_content.empty:
        return gr.update()
    df1 = table_content
    page_num = CURRENT_SESSION.current_page
    start = (page_num - 1) * CURRENT_SESSION.rows_per_page
    end = min(start + CURRENT_SESSION.rows_per_page, CURRENT_SESSION.total_pages)
    df2 = CURRENT_SESSION.display_df[start:end]
    print('====================table_change start====================\n')
    for col in ('gender', 'age'):
        for i in range(len(df1)):
            if CURRENT_SESSION.display_df.at[start + i, col] != df1.loc[i, col]:
                print(f'[line:{i}, col:{col}]:\t{CURRENT_SESSION.display_df.at[start + i, col]}->{df1.loc[i, col]}\n')
                CURRENT_SESSION.display_df.at[start + i, col] = df1.loc[i, col]
    print('====================table_change end====================\n')
    return df2


with gr.Blocks() as demo:
    load_btn = gr.Button("Load", elem_id="load_btn", interactive=True)
    table_output = gr.Dataframe(visible=True, label="table", show_label=False)


    load_btn.click(
        fn=load_file,
        inputs=None,
        outputs=[table_output]
    )
    table_output.change(
        fn=table_change,
        inputs=[table_output],
        outputs=[table_output]
    )

Screenshot

No response

Logs

System Info

Ubuntu: 20.04
Python: 3.10.16
gradio: 5.38.0
gradio_client: 1.11.0

Severity

Blocking usage of gradio

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions