Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gr.Tabs(selected=X) doesn't work when more than one component reference returned for event outputs #7089

Closed
1 task done
dwipper opened this issue Jan 20, 2024 · 7 comments
Assignees
Labels
bug Something isn't working pending clarification Regression Bugs did not exist in previous versions of Gradio

Comments

@dwipper
Copy link

dwipper commented Jan 20, 2024

Describe the bug

After upgrading to Gradio 4.15.0, it appears that gr.Tabs(selected=X) doesn't work if other components are included in the same return statement, i.e. return gr.Tabs(selected=2), gr.Tab(interactive=True). See the below code example.

This appears to be a somewhat related issue, but not exactly the same: #7085

Have you searched existing issues? 🔎

  • I have searched and found no existing issues

Reproduction

import gradio as gr

def change_tab_params():

    return gr.Tab(interactive=True, visible=True)

def change_to_tab_two():

    #return gr.Tabs(selected=2), gr.Tab(label="New tab two") #This won't navigate
    #return gr.Tabs(selected=2), gr.Tab(interactive=True) #This won't navigate
    return gr.Tabs(selected=2) #This will navigate

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Tabs() as tabs:
            with gr.Tab(id=1, label="Tab 1", visible=True, interactive=True) as tab_one:
            #with gr.Tab(id=1, label="Tab 1") as tab_one:
                tab_one_tbox = gr.Textbox(label="Tab One Textbox")
                tab_one_btn = gr.Button(value="Change Tab")
            with gr.Tab(id=2, label="Tab 2", visible=True, interactive=False) as tab_two:
                tab_two_tbox = gr.Textbox(label="Tab Two Textbox")
                #tab_one_btn.click(fn=change_to_tab_two, inputs=None, outputs=[tabs, tab_two]) #This doesn't navigate
                #tab_one_btn.click(fn=change_to_tab_two,inputs=None, outputs=[tabs])  # This does navigate
                tab_one_btn.click(fn=change_tab_params,inputs=None,outputs=[tab_two]).then(fn=change_to_tab_two, inputs=None, outputs=[tabs]) #This does navigate

demo.launch()

Screenshot

NA

Logs

No errors logged

System Info

------------------------------
Operating System: Darwin
gradio version: 4.15.0
gradio_client version: 0.8.1

------------------------------------------------
gradio dependencies in your environment:

aiofiles: 22.1.0
altair: 5.1.2
fastapi: 0.104.0
ffmpy: 0.3.1
gradio-client==0.8.1 is not installed.
httpx: 0.25.0
huggingface-hub: 0.19.4
importlib-resources: 6.1.0
jinja2: 3.1.2
markupsafe: 2.1.1
matplotlib: 3.7.2
numpy: 1.24.3
orjson: 3.9.9
packaging: 23.1
pandas: 2.0.3
pillow: 9.4.0
pydantic: 2.4.2
pydub: 0.25.1
python-multipart: 0.0.6
pyyaml: 6.0
ruff: 0.1.14
semantic-version: 2.10.0
tomlkit==0.12.0 is not installed.
typer: 0.9.0
typing-extensions: 4.8.0
uvicorn: 0.23.2
authlib; extra == 'oauth' is not installed.
itsdangerous; extra == 'oauth' is not installed.


gradio_client dependencies in your environment:

fsspec: 2023.10.0
httpx: 0.25.0
huggingface-hub: 0.19.4
packaging: 23.1
typing-extensions: 4.8.0
websockets: 11.0.3

Severity

I can work around it

@dwipper dwipper added the bug Something isn't working label Jan 20, 2024
@dwipper dwipper changed the title gr.Tabs(selected=X) doesn't work when more than one component reference returned as for outputs gr.Tabs(selected=X) doesn't work when more than one component reference returned for event outputs Jan 20, 2024
@abidlabs abidlabs added the Regression Bugs did not exist in previous versions of Gradio label Jan 21, 2024
@hannahblair hannahblair self-assigned this Jan 23, 2024
@hannahblair
Copy link
Collaborator

Hey @dwipper! Thanks for raising this. Sorry about that! My PR #7107 fixes this I believe. I've just tested with your demo (thanks for including that!) and I think it behaves as expected now. Would you mind trying the latest version of main and confirming this?

@dwipper
Copy link
Author

dwipper commented Jan 23, 2024

@hannahblair Thanks for working on this so quickly. Here's what I found:

  1. I installed the whl: pip install https://gradio-builds.s3.amazonaws.com/88d899e9633ff04400de7866d25005aa925a2ad9/gradio-4.15.0-py3-none-any.whl

I tested this code:

def change_to_tab_two():
    return gr.Tabs(selected=2) #This will navigate

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Tabs() as tabs:
            with gr.Tab(id=1, label="Tab 1", visible=True, interactive=True) as tab_one:
                tab_one_tbox = gr.Textbox(label="Tab One Textbox")
                tab_one_btn = gr.Button(value="Change Tab")
            with gr.Tab(id=2, label="Tab 2", visible=True, interactive=False) as tab_two:
                tab_two_tbox = gr.Textbox(label="Tab Two Textbox")
                tab_one_btn.click(fn=change_to_tab_two,inputs=None, outputs=[tabs])  # This does navigate

demo.launch()

The app navigated to the inactive tab, and the tab stayed inactive when I clicked back to the 1st tab. This was the previous behavior. I'm not clear if this is the desired behavior or not? #7090

  1. I tested this code in which the 2nd tab is active and visible, so the tab should be renamed, and navigation should work:
def change_to_tab_two():
    return gr.Tabs(selected=2), gr.Tab(label="New tab two label") #This won't navigate

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Tabs() as tabs:
            with gr.Tab(id=1, label="Tab 1", visible=True, interactive=True) as tab_one:
                tab_one_tbox = gr.Textbox(label="Tab One Textbox")
                tab_one_btn = gr.Button(value="Change Tab")
            with gr.Tab(id=2, label="Tab 2", visible=True, interactive=True) as tab_two:
                tab_two_tbox = gr.Textbox(label="Tab Two Textbox")
                tab_one_btn.click(fn=change_to_tab_two, inputs=None, outputs=[tabs, tab_two]) 

The result was that the tab was renamed, but the app did not navigate to the 2nd tab, which was the previous issue.

  1. It's worth noting that this code does work, i.e. the Textbox on 2nd page is renamed and the app navigates to the 2nd page, so it seems like the bug isn't about passing multiple component references back, but specifically passing a gr.Tab back to the calling event.
def change_to_tab_two():
    return gr.Tabs(selected=2), gr.Textbox(label="Textbox two new label")

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Tabs() as tabs:
            with gr.Tab(id=1, label="Tab 1", visible=True, interactive=True) as tab_one:
                tab_one_tbox = gr.Textbox(label="Tab One Textbox")
                tab_one_btn = gr.Button(value="Change Tab")
            with gr.Tab(id=2, label="Tab 2", visible=True, interactive=True) as tab_two:
                tab_two_tbox = gr.Textbox(label="Tab Two Textbox",interactive=False)
                tab_one_btn.click(fn=change_to_tab_two, inputs=None, outputs=[tabs, tab_two_tbox]) #This doesn't navigate

demo.launch()

@hannahblair
Copy link
Collaborator

Thanks for the helpful response @dwipper!

Hmm, have you cleared your cache? 🤔 That wheel file produces the expected behaviour for me. I've created a Space here with all your demos above with the wheel installed and everything looks ok.

@dwipper
Copy link
Author

dwipper commented Jan 24, 2024

@hannahblair Yep, that was it. I uninstalled, then reinstalled the .whl. Just to verify:

  1. The app should navigate with multiple return components.
  2. If the target tab is disabled, navigating to the tab will enable the tab, and navigate.
  3. The Textbox on the 2nd tab will be enabled.

This was the behavior I saw in this code:

def change_to_tab_two():
    return gr.Tabs(selected=2), gr.Tab(interactive=True), gr.Textbox(interactive=True)

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Tabs() as tabs:
            with gr.Tab(id=1, label="Tab 1", visible=True, interactive=True) as tab_one:
                tab_one_tbox = gr.Textbox(label="Tab One Textbox")
                tab_one_btn = gr.Button(value="Change Tab")
            with gr.Tab(id=2, label="Tab 2", visible=True, interactive=False) as tab_two:
                tab_two_tbox = gr.Textbox(label="Tab Two Textbox", interactive=False)
                tab_one_btn.click(fn=change_to_tab_two, inputs=None, outputs=[tabs, tab_two, tab_two_tbox]) 


demo.launch()

@hannahblair
Copy link
Collaborator

@dwipper Great!

Yep, the 3 points you outlined reflect the behaviour I'm seeing in your demo. Is that not the functionality you expected?

@dwipper
Copy link
Author

dwipper commented Jan 24, 2024

@hannahblair Yes. I did also notice that if a Tab is visible=False or interactive=False, the app won't navigate to the Tab, which makes sense. I just wonder if the code should throw an error? Visually nothing happens, and from a coding side, it appears that everything is "normal". But I leave it to you and the engineering gurus, as to whether that makes sense or not.

@hannahblair
Copy link
Collaborator

Yeah I agree, actually! We'll discuss the best approach for that UX-wise and add that as an improvement 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working pending clarification Regression Bugs did not exist in previous versions of Gradio
Projects
None yet
Development

No branches or pull requests

3 participants