Phoenix
Phoenix copied to clipboard
wx.Accessible does not work in 64-bit builds of wxpython
Operating system: Windows 10 21H1 (64-bit) build 19043.1237 wxPython version & source: '4.1.1 msw (phoenix) wxWidgets 3.1.5' Python version & source: Python 3.9.7 official builds from python.org
Description of the problem:
Accessibility changes to a wx control using the wx.Accessible mechanism are not effective in 64-bit builds of wxpython. In 32-bit builds accessibility annotations work as expected.
Code Example (click to expand)
import wx
class ContentViewAccessible(wx.Accessible):
def GetRole(self, childId):
return (wx.ACC_OK, wx.ROLE_SYSTEM_DOCUMENT)
def GetDescription(self, childId):
return (wx.ACC_OK, "Document Page")
class ContentViewCtrl(wx.TextCtrl):
def __init__(self, *args, **kwargs):
super().__init__()
super().Create(
*args,
style=wx.TE_READONLY
| wx.TE_MULTILINE
| wx.TE_RICH2
| wx.TE_AUTO_URL
| wx.TE_NOHIDESEL,
**kwargs,
)
self.SetAccessible(ContentViewAccessible(self))
This seems strange. Do you have a complete, runnable example that reproduces the problem?
I can't tell about 32 bits, but I can verify that in 64 bit version, accessibility has some issues. Even this simple code does not work as expected. I am testing it with following configuration: Edition Windows 10 Pro Version 21H1 OS build 19043.1348 Experience Windows Feature Experience Pack 120.2212.3920.0 Python version 3.9.7 and the screen reader is NVDA version 2021.2. Code to reproduce:
`import wx app=wx.App()
class main_window(wx.Frame): def init(self): wx.Frame.init(self, parent=None, title="Test", name="test") # The name attribute here is used so that when the app starts, screen reader does not read the word "frame". In this case and environment, it has no effect. panel=wx.Panel(self) test_input=wx.TextCtrl(panel, name="Enter some text here!") # or you could comment the line above and uncomment the two lines below. The result is the same. In third case, if you initialize element with the blank string, no success then as well. # test_input=wx.TextCtrl(panel) # test_input.SetName("Enter some text here!") ok_button=wx.Button(panel, label="OK!") # the label for the button will work, however when tabbing or shift+tabbing to the text field, nothing will work. self.Show()
main_window() app.MainLoop()`
``
The screen reader speaks the title of an application and then edit field, but no "enter some text" is hurd. As you can see, the screen reader output is not what it should be. I have even tried tabbing and then coming back to it again, button's label is read aloud, while text field's is not. I have also compared the screen reader logs on a button vs on a text field. Here they are. While focused on the text field and bringing up the logs, this is what I've got: (Note, I am only sharing snippets of logs of values that are linked to accessibility properties). Developer info for navigator object: name: None role: ROLE_EDITABLETEXT roleText: None states: STATE_FOCUSABLE, STATE_FOCUSED isFocusable: True hasFocus: True description: None location: RectLTWH(left=110, top=139, width=132, height=23) value: '' windowClassName: 'Edit' windowControlID: -31992 windowStyle: 1375797376 extendedWindowStyle: 512 windowText: '' displayText: '' IAccessibleObject: <POINTER(IAccessible) ptr=0xceac098 at 35578a0> IAccessibleChildID: 0 IAccessible event parameters: windowHandle=133296, objectID=-4, childID=0 IAccessible accName: None IAccessible accRole: ROLE_SYSTEM_TEXT IAccessible accState: STATE_SYSTEM_FOCUSED, STATE_SYSTEM_FOCUSABLE, STATE_SYSTEM_VALID (1048580) IAccessible accDescription: None IAccessible accValue: ''
The log below is when I am focused on button: Developer info for navigator object: name: 'OK!' role: ROLE_BUTTON roleText: None states: STATE_FOCUSABLE, STATE_FOCUSED isFocusable: True hasFocus: True description: None location: RectLTWH(left=108, top=136, width=93, height=28) value: None windowClassName: 'Button' windowControlID: -31991 windowStyle: 1442906113 extendedWindowStyle: 0 windowText: 'OK!' displayText: 'OK!' IAccessibleObject: <POINTER(IAccessible) ptr=0x75ab568 at 3557850> IAccessibleChildID: 0 IAccessible event parameters: windowHandle=133294, objectID=-4, childID=0 IAccessible accName: 'OK!' IAccessible accRole: ROLE_SYSTEM_PUSHBUTTON IAccessible accState: STATE_SYSTEM_FOCUSED, STATE_SYSTEM_DEFAULT, STATE_SYSTEM_FOCUSABLE, STATE_SYSTEM_VALID (1048836) IAccessible accDescription: None IAccessible accValue: None
So this is what screen reader sees. After searching through the internet for possible solutions, I saw that 4.0.4 had this issue but then in 4.1.0 it was fixed. Version 4.1.1, this one is partially coming back up again. Thanks, Nick.
Yup, I'm able to reproduce this as well, on the latest WXPython (4.1.1).
Hello, I started learning WXPython today and I also try to understand how to add lable for a TextCTRL widget for it to be read by screen reader, but keyword "Label" isn't defined in this widget's properties. How can I add a label? Thank you!
@sevapopov2
First create a wx.StaticText control with the label you want, and then add it immediately before the TextCtrl in the Sizer.
For wxpython 4.20 this issue has been fixed.