Hello. We trying to integrate WXPython widgets onto a pygame window. Despite many resources that claim this is not doable on the internet, we didn't give up, and managed to get it working. The reason we want this is because I want to add advanced text editing commands like selecting, cutting, copying etc., to our game zero hour assault. Since writeing these from scratch is time-consuming, we decided to use native windows controls. However, this required to open a different window for the text control, but we want it to be in the same window. That's why we integrated WXPython widgets to my pygame window. My question is, my code works, but when the textbox appears in the window, nvda for some reason reads the pygame's window title and then reads the label of the textbox, like so:
Zero hour assault 1.0. Enter your username edit multiline
But since the window title doesn't change, it shouldn't read it, it should only say
Enter your username edit multiline
Similary, when I close the textbox, it again reads just the game window title, even if it doesn't change, like this.
Zero hour assault 1.0.
Normaly, it shouldn't say anything.
In summarily, when I open the textbox, it should only say the textbox title, and when I close it, it shouldn't say anything. How can I fix this issue? here's my code.
import wx
import ctypes
import pygame
class CustomTextInputDialog:
def _init_(self, title):
window_handle = int(pygame.display.get_wm_info()["window"])
self.frame = wx.Frame(None) # since wxpython widgets require a parent as a wxpython object, I created this frame, It is actualy not shown on the screen.
self.label = wx.StaticText(self.frame, label=title)
self.text_ctrl = wx.TextCtrl(self.frame, style=wx.TE_MULTILINE, size=(1920,1080)) # I did the input fullscreen because nvda was reading 5-6 chars in each line if the line is longer when I press up and down arrow.
self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.on_key_down)
ctypes.windll.user32.SetParent(self.text_ctrl.GetHandle(), window_handle)
ctypes.windll.user32.SetParent(self.label.GetHandle(), window_handle)
def on_key_down(self, event):
keycode = event.GetKeyCode()
if keycode == wx.WXK_RETURN:
if event.ShiftDown(): # I want new line with shift enter not enter, so that's why I wrote this. Enter submits input.
current_pos = self.text_ctrl.GetInsertionPoint()
text = self.text_ctrl.GetValue()
new_text = text[:current_pos] + '\n' + text[current_pos:]
self.text_ctrl.SetValue(new_text)
self.text_ctrl.SetInsertionPoint(current_pos + 1)
else:
self.on_ok(None)
elif keycode == wx.WXK_ESCAPE:
self.on_cancel(None)
else:
event.Skip()
def on_ok(self, event):
self.entered_text = self.text_ctrl.GetValue()
self.frame.Destroy()
app.ExitMainLoop()
def on_cancel(self, event):
self.frame.Destroy()
app.ExitMainLoop()
self.entered_text = ""
app=wx.App(False)
def get_input(title):
dialog = CustomTextInputDialog(title)
timer = wx.Timer()
def on_timer(event):
dialog.text_ctrl.SetFocus() # I did this because when I alt tab out of the window and reactivate the window, the focus wasn't getting to the text box, so this fixes it.
timer.Bind(wx.EVT_TIMER, on_timer)
timer.Start(1)
app.MainLoop()
return dialog.entered_text
There's also another issue I forgot to mention, when I alt tab out of the window and then reactivate it, the focus is in the input box, but nvda doesn't read anything at all. When I type, it reads the letters, but for example when I move with left and right arrows or select text, it doesn't read anything, but it actualy selects text, I tested. The way to fix this is to press the applications key to open the context menu and press escape to close it, and nvda works normaly. Or another way is to open nvda menu with nvda+n, and press escape. And for some reason this doesn't happen if i minimize the window with windows+m first, it only happens if i dirrectly use alt tab without minimizing it.
How can I fix these issues?
Regards...
Bilal