Showing panel issue in a MDI WX code

Hi all,

first time post. I am creating a WX program and having issues with showing the panels. The issues I am having:

  1. Ctrl+tab does not switch between panels and set the keyboard focus to the first child control of the panel.
  2. When using alt+1, alt+2 or alt+3 or via the menu window. The panel is not being displayed. You get a blank screen. when the progrma launches, Panel1 is shown fine.
  3. When I switch to another program and back to the Wx program. Keyboard focus is not on the last control with keyboard focus.
  4. This program is being design to support keyboard and screen reader users.

Below is the frame class in full. Let me know if you require the panel classes.

class MyFrame(wx.MDIParentFrame):
def init(self):
wx.MDIParentFrame.init(self, None, title=“Library”)
self.panel1 = EditPanel(self, self)
self.panel2 = RecordListPanel(self)
self.panel3 = RecordPanel(self, self)

    self.panel1.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
    self.panel2.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
    self.panel3.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)

    self.panel1.Show()

    self.SetMenuBar(self.create_menubar())
    self.SetupShortcutKeys()
    self.Bind(wx.EVT_CHILD_FOCUS, self.OnChildFocus)
    #self.SetSize((1920, 1080))
    self.Maximize()
    self.Center()
    # Set focus on child edit object of Panel1
    self.panel1.edit.SetFocus()
    self.last_focus_id = None  # variable to store the ID of the control with focus

def onTab(self, event):
    current_panel = self.GetActiveChild()
    if current_panel is None:
        current_panel = self.GetChildren()[0]
        panel = event.GetEventObject()
    panels = self.GetChildren()
    if wx.GetKeyState(wx.WXK_CONTROL):
        if wx.GetKeyState(wx.WXK_SHIFT):
            previous_panel = current_panel.GetPrevSibling()
            if previous_panel:
                if previous_panel== panels[1]:
                    # skip the status bar panel. Need to find a method of removing the status bar from the windowList object. Currently defined in the EditPanel class.
                    previous_panel = panels[0]
                self.switchPanel(previous_panel)
            else:
                self.switchPanel(panels[0]) # first panel.
        else:
            next_panel = current_panel.GetNextSibling()
            if next_panel:
                if next_panel == panels[1]:
                    next_panel = panels[2] 
                self.switchPanel(next_panel)
            else:
                self.switchPanel(panels[-1])

def OnSetFocus(self, event):
    print ("OnSetFocus method")
    event.Skip()
    self.SetTitle(event.GetEventObject().GetParent().GetTitle())
    event.GetEventObject().GetChildren()[0].SetFocus()

    # save the ID of the control with focus
    self.last_focus_id = event.GetId()

def OnChildFocus(self, event):
    print ("OnChildFocus method")
    children = event.GetWindow().GetChildren()
    if children:
        children[0].SetFocus()

        # save the ID of the control with focus
        self.last_focus_id = event.GetId()

def switchPanel(self, panel):
    print (f"switch panel {panel}")
    current_panel = self.GetActiveChild()
    #current_panel = self.GetActiveChild()
    if current_panel is None:
        current_panel = self.GetChildren()[0]

    #if current_panel:
        #if current_panel.GetNextSibling() == panel:
            #print ("getting next sibling ")
            #self.ActivateNext()
        #elif current_panel.GetPrevSibling() == panel:
            #print ("getting prior control")
            #self.ActivatePrevious()
        #else:
            #print ("hiding current panel")
    current_panel.Hide()

    # restore the focus state of the window
    #if self.last_focus_id:
        #control = wx.FindWindowById(self.last_focus_id)
        #if control:
            #control.SetFocus()

    print ("showing and focusing on panel")
    #panel.SetFocus()
    if panel is self.panel1:
        print ("panel1 has focus")
        self.panel1.edit.SetFocus()
    elif panel is self.panel2:
        self.panel2.list_ctrl.SetFocus()
    elif panel is self.panel3:
        self.panel3.title_text.SetFocus()

def on_exit(self, event):
    self.Close()


def create_menubar(self):
    self.menubar = wx.MenuBar()
    # Create the "Options" menu
    self.options_menu = wx.Menu()
    self.save_record_item = self.options_menu.Append(wx.ID_ANY, "Save Record\tCtrl+S", "Save to database")
    self.Bind(wx.EVT_MENU,self.panel1.saveDb, self.save_record_item)
    self.next_file_item = self.options_menu.Append(wx.ID_ANY, "Next file\tCtrl+N", "Load next file")
    self.prior_file_item = self.options_menu.Append(wx.ID_ANY, "Prior file\tCtrl+P", "Load prior file")
    self.review_record_item = self.options_menu.Append(wx.ID_ANY, "Review Record\tCtrl+r", "Review  record")
    self.Bind(wx.EVT_MENU,self.panel1.ShowMemoryRecord, self.review_record_item)
    self.Bind(wx.EVT_MENU,self.panel1.nextBook, self.next_file_item)
    self.Bind(wx.EVT_MENU,self.panel1.priorBook, self.prior_file_item)
    self.clear_record_item = self.options_menu.Append(wx.ID_ANY, "Clear Record\Alt+I", "Clear record in memory")
    self.Bind(wx.EVT_MENU,self.panel1.clearRecord, self.clear_record_item)
    self.exit_item = self.options_menu.Append(wx.ID_EXIT, "Exit", "Exit the program")
    self.Bind(wx.EVT_MENU, self.on_exit, self.exit_item) 
    self.menubar.Append(self.options_menu, "&Options")

    # Create the "Save to record" menu
    self.save_menu = wx.Menu()
    self.title_item = self.save_menu.Append(wx.ID_ANY, "Title\tAlt+T", "Save book title")
    self.Bind(wx.EVT_MENU, lambda event: self.panel1.updateMemoryField(FieldNames.TITLE.value), self.title_item)
    self.author_item = self.save_menu.Append(wx.ID_ANY, "Author\tAlt+A", "Save book author")
    self.Bind(wx.EVT_MENU, lambda event: self.panel1.updateListMemoryField(FieldNames.AUTHORS.value), self.author_item)
    self.series_item = self.save_menu.Append(wx.ID_ANY, "Series\tAlt+S", "Save book Series")
    self.Bind(wx.EVT_MENU, lambda event: self.panel1.updateMemoryField(FieldNames.SERIES.value), self.series_item)
    self.seriesNo_item = self.save_menu.Append(wx.ID_ANY, "SeriesNo\tCtrl+3", "Save Series No")
    self.Bind(wx.EVT_MENU, lambda event: self.panel1.updateMemoryField(FieldNames.SERIES_NO.value), self.seriesNo_item)
    self.genre_item = self.save_menu.Append(wx.ID_ANY, "Genre\tAlt+G", "Save book genre")
    self.Bind(wx.EVT_MENU, lambda event: self.panel1.updateListMemoryField(FieldNames.GENRES.value), self.genre_item)
    self.description_item = self.save_menu.Append(wx.ID_ANY, "Description\tAlt+D", "Save book description")
    self.Bind(wx.EVT_MENU, lambda event: self.panel1.updateMemoryField(FieldNames.DESCRIPTION.value), self.description_item)
    self.aboutAuthor_item = self.save_menu.Append(wx.ID_ANY, "About Author\tAlt+B", "Save about author")
    self.Bind(wx.EVT_MENU, lambda event: self.panel1.UpdateAboutAuthor(FieldNames.AUTHORS.value), self.aboutAuthor_item)
    self.narrator_item = self.save_menu.Append(wx.ID_ANY, "Narrator\tAlt+N", "Save book narrator")
    self.Bind(wx.EVT_MENU, lambda event: self.panel1.updateListMemoryField(FieldNames.NARRATORS.value), self.narrator_item)
    self.release_item = self.save_menu.Append(wx.ID_ANY, "Release Date\tAlt+R", "Save book release date")
    self.Bind(wx.EVT_MENU,lambda event: self.panel1.updateMemoryField(FieldNames.RELEASE.value), self.release_item)
    self.duration_item = self.save_menu.Append(wx.ID_ANY, "Duration\tCtrl+D", "Save book duration")
    self.Bind(wx.EVT_MENU,lambda event: self.panel1.updateMemoryField(FieldNames.DURATION.value), self.duration_item)
    self.copyright_item = self.save_menu.Append(wx.ID_ANY, "Copyright\tAlt+C", "Save book copyright")
    self.Bind(wx.EVT_MENU, lambda event: self.panel1.updateMemoryField(FieldNames.COPYRIGHT.value), self.copyright_item)
    self.publisher_item = self.save_menu.Append(wx.ID_ANY, "Publisher\tAlt+P", "Save book publisher")
    self.Bind(wx.EVT_MENU, lambda event: self.panel1.updateMemoryField(FieldNames.PUBLISHER.value), self.publisher_item)
    self.misc_item = self.save_menu.Append(wx.ID_ANY, "Misc\tAlt+M", "Save book misc")
    self.Bind(wx.EVT_MENU, lambda event: self.panel1.updateMemoryField(FieldNames.MISC.value), self.misc_item)
    self.menubar.Append(self.save_menu, "Sa&ve to record")

    # Create the "Windows" menu
    self.windows_menu = wx.Menu()
    self.switch_panel1_item = self.windows_menu.Append(wx.ID_ANY, "Switch to Edit Panel\tAlt+1", "Switch to the edit panel")
    self.Bind(wx.EVT_MENU, lambda event: self.switchPanel(self.panel1), self.switch_panel1_item)
    self.switch_panel2_item = self.windows_menu.Append(wx.ID_ANY, "Switch to Record List Panel\tAlt+2", "Switch to the record list panel")
    self.Bind(wx.EVT_MENU, lambda event: self.switchPanel(self.panel2), self.switch_panel2_item)
    self.switch_panel3_item = self.windows_menu.Append(wx.ID_ANY, "Switch to Record Panel\tAlt+3", "Switch to the record panel")
    self.Bind(wx.EVT_MENU, lambda event: self.switchPanel(self.panel3), self.switch_panel3_item)
    self.menubar.Append(self.windows_menu, "&Windows")
    self.SetMenuBar(self.menubar)

def SetupShortcutKeys (self):
    self.tab_id = wx.NewIdRef()
    # Set up the accelerator table
    self.accel_tbl = wx.AcceleratorTable([
        (wx.ACCEL_CTRL, ord('S'), self.save_record_item.GetId()),
        (wx.ACCEL_CTRL, ord('N'), self.next_file_item.GetId()),
        (wx.ACCEL_CTRL, ord('P'), self.prior_file_item.GetId()),
        (wx.ACCEL_CTRL, ord('R'), self.review_record_item.GetId()),
        (wx.ACCEL_ALT, ord('I'), self.clear_record_item.GetId()),
        (wx.ACCEL_ALT, ord('T'), self.title_item.GetId()),
        (wx.ACCEL_ALT, ord('A'), self.author_item.GetId()),
        (wx.ACCEL_ALT, ord('S'), self.series_item.GetId()),
        (wx.ACCEL_CTRL, ord('3'), self.seriesNo_item.GetId()),
        (wx.ACCEL_ALT, ord('G'), self.genre_item.GetId()),
        (wx.ACCEL_ALT, ord('D'), self.description_item.GetId()),
        (wx.ACCEL_ALT, ord('B'), self.aboutAuthor_item.GetId()),
        (wx.ACCEL_ALT, ord('N'), self.narrator_item.GetId()),
        (wx.ACCEL_ALT, ord('R'), self.release_item.GetId()),
        (wx.ACCEL_CTRL, ord('D'), self.duration_item.GetId()),
        (wx.ACCEL_ALT, ord('C'), self.copyright_item.GetId()),
        (wx.ACCEL_ALT, ord('P'), self.publisher_item.GetId()),
        (wx.ACCEL_ALT, ord('M'), self.misc_item.GetId()),
        (wx.ACCEL_ALT, ord('1'), self.switch_panel1_item.GetId()),
        (wx.ACCEL_ALT, ord('2'), self.switch_panel2_item.GetId()),
        (wx.ACCEL_ALT, ord('3'), self.switch_panel3_item.GetId()),
        (wx.ACCEL_CTRL, wx.WXK_TAB, self.tab_id),
        (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, wx.WXK_TAB, self.tab_id)
    ])
    self.SetAcceleratorTable(self.accel_tbl)
    self.Bind(wx.EVT_MENU, self.onTab, id=self.tab_id)

class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame()
self.frame.Show(True)
return True

if name == ‘main’:
app = MyApp(0, True)
app.MainLoop()
Any tips or ways of improving the keyboard focus management are welcomed.