Is it possible to react to both single and double clicks on DataTable rows while keeping header non-interactive? #6511
|
I have a MVE, but I feel like this must be a quick yes or no based on the parts of DataTable that are/aren't exposed public. I am new to both python and textual. Over a couple days I have come at this from numerous approaches, mainly centered around Differentiating between a single and double click in order to keep the built-in Also a DataTable with "reactive header row", which I have working with some jank and running a But that's secondary to: Making header row either ignore double-click or completely non-interactive while maintaining that functionality on the rest of the table rows (index > -1). Right now, I am throwing the kitchen sink at making the header not crash everything when it gets double-clicked. Single-click on header is fine and does nothing, as expected. Overriding my subclassed DataTable There must be something silly I'm not considering here. My I am almost certain I tried getting around that |
Replies: 2 comments 3 replies
|
I got it working finally BUT, the thing is, it will now only Lots of gross code there, I know. I wanted to do this without AI, but with the requisite help from StackOverflow/Google, so my methods are based on both this very GitHub repo examples and help forum and SO logic. If I'm doing something monumentally stupid, please correct. EDIT: This is with: |
|
The crash is because you're reimplementing DataTable's own header branch ( Two facts that make this easy:
And the bit that isn't obvious: your subclass from textual import events, work
from textual.widgets import DataTable
class MyTable(DataTable):
def on_click(self, event: events.Click) -> None:
row = event.style.meta.get("row", -1)
if row < 0: # header or off a real row: ignore
event.prevent_default() # stops the built-in header handling too
return
if event.chain == 2: # double-click on a real row
event.prevent_default() # skip the built-in select for this click
self.open_modal(row)
@work
async def open_modal(self, row: int) -> None:
await self.app.push_screen_wait(MyModal(row))
Single-click still flows through to your existing |
The crash is because you're reimplementing DataTable's own header branch (
self.ordered_columns[column_index]) in your override, and hitting it with a column index that isn't a real column. You don't need to touch that path at all. Add a plainon_clickon your subclass instead of overriding_on_click, and let the built-in one keep running.Two facts that make this easy:
Clickevents carry achainattribute.event.chain == 2is a double-click.event.style.metaasrow/column. The header row isrow == -1.And the bit that isn't obvious: your subclass
on_clickand the built-inDataTable._on_clickare on different classes in the MRO, so both fire. That means s…