Textualize / textual

The lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser.
https://textual.textualize.io/
MIT License
25.62k stars 788 forks source link

DataTable RowKey (etc.) (unnecessarily?) restricted to str #3492

Open paravoid opened 1 year ago

paravoid commented 1 year ago

I'm trying to key a data table row, by a tuple, rather than by a string¹.

This seems to work. add_row(*row_data, key=(category, id)) when adding the row just works, and unpacking with category, id = row_key.value on e.g. an action also works.

The only issue that I've identified so far is: mypy complains, for two reasons: 1) add_row() expects a key: str | None = None, and wraps that into a RowKey(key) unconditionally. Other functions at least, like update_cell(), take a row_key: RowKey | str, and do if isinstance(row_key, str): row_key = RowKey(row_key).

2) class RowKey is a subclass of StringKey, and that has a value: str | None, as it is, well, supposed to wrap strings. The implementation, however, is very simple, and if value is a Hashable, everything else seems to fall into order. In fact I think s/str/Hashable/ would make everything work here.

1: My use case is that I have an interface with a Tree view on the left, a data table on the right and a button to act on the table row. Once you pick a category (say, "customer") from the tree, a table specific to that category is shown (say, "invoices"). When I hit the button, I'd like to act on the row, which is keyed by (category, row). I suppose I could do that by subclassing the DataTable and storing the category as an attribute there? But I tried to keep things flat and simple first. Let me know if you think that I'm stretching the internals too much by trying to do something flawed from the get-go :)

boxed commented 1 month ago

I hit this too.

I think a different approach could be to have an extra param that you can attach to each row. In win32 nomenclature that's "user data", which is super useful.

I would argue that a table is better modeled as a list of some type and then some way to project that into the tuple of cells. This would solve this too.