Hi all,
I hope someone can help. I want to create a dataview or a listview using WX. The key requirements are:
- 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.
- The right arrow key does the same as the left arrow but moves backwards through the columns.
- 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.
- 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.