toga icon indicating copy to clipboard operation
toga copied to clipboard

Add a setter for `Table.selection`

Open vzool opened this issue 1 year ago • 8 comments

What is the problem or limitation you are having?

I can't unselect Row after selecting it on toga.Table()

Describe the solution you'd like

I use the on_select action on toga.Table() to move from the parent page into the children pages. The Row will be selected and the page changed. So, when I get back, I can't select the same Row again unless selecting a different Row and then go back to the wanted Row.

Describe alternatives you've considered

I think unselect([Row]) => unselect multiple Row and unselect(None) => unselect all[Row] on toga.Table()

Additional context

Related:

  • https://github.com/beeware/toga/issues/2239

vzool avatar Jul 10 '24 07:07 vzool

https://github.com/beeware/toga/assets/4952736/820927ef-4f2e-4bce-abae-33efd85122c6

vzool avatar Jul 10 '24 07:07 vzool

Thanks for the report: a cleaner way of doing this would be to implement a setter on Table.selection.

Meanwhile, if all you want to do is clear the selection, you may be able to do that by re-assigning your table's data property.

mhsmith avatar Jul 10 '24 10:07 mhsmith

Great, it does work! Thanks for Help

vzool avatar Jul 10 '24 13:07 vzool

This also came up on StackOverflow.

mhsmith avatar Aug 19 '24 13:08 mhsmith

Hello there. I'm working on a check list class based on Table and found this issue. I think this method/setter could have this working:

table.selection=row
#we may even do this
table.selection+=row

or

table.select(*index)

I suppose it would be powerful. :)

And I notice that toga_android have implemented the similar method, i.e. Table.add_selection and Table.remove_selection, but it's a pity that they are now private currently for Android.

MeteorShower2004 avatar Nov 15 '24 06:11 MeteorShower2004

@MeteorShower2004 A setter would be the API that is consistent with the rest of Toga - so:

table.selection = row
table.selection+= row2
table.selection = [row3, row4]
table.selection = None

You're correct that the Android implementation has the many of, if not all the pieces necessary to implement most of this API; however, there's likely some methods missing to deal with things like overlapping selection changes (e.g., [row1, row2] -> [row2, row3] without doing "clear and reselect everything").

It's also worth noting that the Android table implementation needs to be massively re-written; it's currently a naïve port of a "desktop-style" table, rather than being a mobile-appropriate table.

freakboy3742 avatar Nov 16 '24 01:11 freakboy3742

It's also worth noting that the Android table implementation needs to be massively re-written; it's currently a naïve port of a "desktop-style" table, rather than being a mobile-appropriate table.

Thanks for your explanation.

As for my program, it mainly works on Windows and Android. Obviously on PC I can click entry with ctrl or shift down to perform "union" operation and so on. At least winform supports it internally. And I hacked toga_android.Table and suppose long click to select or remove a range of entries.

I think this idea would be useful for implementing this API.

MeteorShower2004 avatar Nov 16 '24 08:11 MeteorShower2004

My workaround:

def select_table_row(table: toga.Table, row_index: int):
    """Select a row in a table programmatically.

    This is a platform-specific workaround for programmatically selecting
    table rows, as Toga doesn't provide a cross-platform API for this.

    Args:
        table: The toga.Table widget
        row_index: The index of the row to select (0-based)
    """
    try:
        platform_system = platform.system()
        if platform_system == 'Windows':
            # WinForms: Access ListView and set item as selected
            list_view = table._impl.native
            if 0 <= row_index < list_view.VirtualListSize:
                # Clear existing selection
                list_view.SelectedIndices.Clear()
                # Select the item and ensure it's visible
                list_view.Items[row_index].Selected = True
                list_view.Items[row_index].Focused = True
                list_view.EnsureVisible(row_index)
                list_view.Focus()
        elif platform_system == "Linux":
            # GTK: Access TreeView through ScrolledWindow
            scrolled_window = table._impl.native
            tree_view = scrolled_window.get_child()
            selection = tree_view.get_selection()
            selection.select_path(row_index)
            tree_view.grab_focus()
        else:
            raise Exception(
                f'Selecting table rows is not supported on system "{platform_system}"!')
    except Exception:
        traceback.print_exc()

masmu avatar Nov 01 '25 18:11 masmu