List view navigation with keyboard help

Hi all,

I hope someone can help. I want to create a dataview or a listview using WX. The key requirements are:

  1. The left arrow key moves to the next column of the row (item) and a screen reader announces the content. The value in the cell of the column is visually identified as being selected.
  2. The right arrow key does the same as the left arrow but moves backwards through the columns.
  3. the up and down arrows selects the current cell (item) in the column you are in. For example: if you have a columns “filenames, date, file type”. If you are in the file type, pressing down arrow will announce the next row file type.
  4. the windows context menu (shift + f10 or right click) is triggered when they are on a specific cell of the column.

Using MS Windows file explorer. This behaviour is found. I am trying to make this work with a windows screen reader so the Vision Impaired user can navigate the content and do an action on that cell.

Here is one attempt I have done:

class RecordDataViewPanel(wx.Panel):
def init(self, parent):
super().init(parent)

    self.dvlc = wx.dataview.DataViewListCtrl(self, style=wx.SUNKEN_BORDER)
    self.dvlc.AppendTextColumn('Book Id', width=100)
    self.dvlc.AppendTextColumn('Title', width=200)
    self.dvlc.AppendTextColumn('Author', width=200)
    self.dvlc.AppendTextColumn('Genre', width=200)
    self.dvlc.AppendTextColumn('Series', width=200)
    self.dvlc.AppendTextColumn('Series NO', width=200)

    self.populate_dvlc()

    self.dvlc.Bind(wx.EVT_KEY_DOWN, self.on_key_down)
    self.dvlc.Bind(wx.dataview.EVT_DATAVIEW_ITEM_ACTIVATED, self.on_item_activated)

def on_item_activated(self, event):
    index = event.GetIndex()
    index = self.dvlc.GetTextValue(index, 0)
    self.GetParent().panel3.populate_fields(index)

def populate_dvlc(self):
    with Session() as session:
        books = session.query(Book).all()
        for book in books:
            row = [book.id, book.title]
            # authors
            authors = ', '.join([author.author for author in book.authors])
            row.append(authors)
            # genres
            genres = ', '.join([genre.genre for genre in book.genres])
            row.append(genres)
            row.append(book.series.series)
            row.append(str(book.series_no))
            self.dvlc.AppendItem(row)
    session.close()

def Show(self, show=True):
    if show:
        # Check for new records and update the list box
        session = Session()
        books = session.query(Book).all()
        num_books = len(books)
        num_items = self.dvlc.GetItemCount()
        if num_books > num_items:
            # Clear the list control and repopulate it with the updated data
            self.dvlc.DeleteAllItems()
            self.populate_dvlc()
    session.close()

    # Call the base class's Show method to actually show/hide the panel
    super().Show(show)

def on_key_down(self, event):
    keycode = event.GetKeyCode()

    # Check if left or right arrow key was pressed
    if keycode == wx.WXK_LEFT or keycode == wx.WXK_RIGHT:
        # Get the current row and column
        item = self.dvlc.GetFirstSelected()
        row = self.dvlc.ItemToRow(item)
        col = self.dvlc.ItemToColumn(item)

        # Move to the next or previous column
        if keycode == wx.WXK_LEFT:
            col -= 1
        elif keycode == wx.WXK_RIGHT:
            col += 1

        # Check if the new column is within bounds
        if col >= 0 and col < self.dvlc.GetColumnCount():
            # Select the new cell
            self.dvlc.Select(row, col)

            # Get the text of the current cell and read it out to the screen reader
            text = self.dvlc.GetTextValue(row, col)
            wx.Accessibility.NotifyEvent(wx.ACC_EVENT_OBJECT_FOCUS, self.dvlc.GetHandle(), wx.ACC_OBJECTID_CLIENT, wx.ACC_SELF, wx.AccessibleText(text))
    else:
        event.Skip()

Any help would be great.

In C++ there’s a wxNavigationKeyEvent class, this might be of help if it’s in wxPython.
You might want to or in style wxTAB_TRAVERSAL to see if that helps in navigation
wxKeyEvent::ShiftDown() should return true if the shift key was down at the time of the event.

it is in wxPython, but useless for C&P like scripting :rofl:

yeah, sorry about that, I just assumed