Scope of keyboard shortcuts

This forum can be used to talk about general design strategies, new ideas and questions in general related to wxWidgets. If you feel your questions doesn't fit anywhere, put it here.
Post Reply
xarx
In need of some credit
In need of some credit
Posts: 3
Joined: Sun Mar 20, 2016 11:52 pm

Scope of keyboard shortcuts

Post by xarx » Mon Mar 21, 2016 12:13 am

When a letter in a widget label is prefixed with "&", the letter is treated for a shortcut. Then, when pressing Alt+<letter>, the corresponding widget is given focus.

The problem is, that the scope where the shortcut can be used is very limitted. It seems to me that from the currently focused widget you can navigate only to other widgets at the same level or below. For instance, take this wxPython script:

Code: Select all

import wx

class TestFrame ( wx.Frame ):
	
	def __init__( self, parent ):
		wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 265,563 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
		
		self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
		
		sbSizer4 = wx.StaticBoxSizer( wx.StaticBox( self, wx.ID_ANY, u"Sizer + panel + sizer" ), wx.VERTICAL )
		
		self.m_panel20 = wx.Panel( sbSizer4.GetStaticBox(), wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
		self.m_panel20.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_INFOBK ) )
		
		gbSizer3 = wx.GridBagSizer( 0, 0 )
		gbSizer3.SetFlexibleDirection( wx.BOTH )
		gbSizer3.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
		
		self.m_panel22 = wx.Panel( self.m_panel20, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
		self.m_panel22.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_ACTIVECAPTION ) )
		
		gbSizer2 = wx.GridBagSizer( 0, 0 )
		gbSizer2.SetFlexibleDirection( wx.BOTH )
		gbSizer2.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
		
		self.m_staticText31 = wx.StaticText( self.m_panel22, wx.ID_ANY, u"Panel + sizer", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.m_staticText31.Wrap( -1 )
		gbSizer2.Add( self.m_staticText31, wx.GBPosition( 0, 0 ), wx.GBSpan( 1, 2 ), wx.ALL, 5 )
		
		self.m_staticText20 = wx.StaticText( self.m_panel22, wx.ID_ANY, u"&A", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.m_staticText20.Wrap( -1 )
		gbSizer2.Add( self.m_staticText20, wx.GBPosition( 1, 0 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )
		
		self.m_textCtrl19 = wx.TextCtrl( self.m_panel22, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
		gbSizer2.Add( self.m_textCtrl19, wx.GBPosition( 1, 1 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )
		
		sbSizer8 = wx.StaticBoxSizer( wx.StaticBox( self.m_panel22, wx.ID_ANY, u"Sizer only" ), wx.HORIZONTAL )
		
		self.m_staticText21 = wx.StaticText( sbSizer8.GetStaticBox(), wx.ID_ANY, u"&B", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.m_staticText21.Wrap( -1 )
		sbSizer8.Add( self.m_staticText21, 0, wx.ALL, 5 )
		
		self.m_textCtrl20 = wx.TextCtrl( sbSizer8.GetStaticBox(), wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
		sbSizer8.Add( self.m_textCtrl20, 0, wx.ALL, 5 )
		
		
		gbSizer2.Add( sbSizer8, wx.GBPosition( 2, 0 ), wx.GBSpan( 1, 2 ), 0, 5 )
		
		self.m_staticText23 = wx.StaticText( self.m_panel22, wx.ID_ANY, u"&C", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.m_staticText23.Wrap( -1 )
		gbSizer2.Add( self.m_staticText23, wx.GBPosition( 3, 0 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )
		
		self.m_textCtrl22 = wx.TextCtrl( self.m_panel22, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
		gbSizer2.Add( self.m_textCtrl22, wx.GBPosition( 3, 1 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )
		
		
		self.m_panel22.SetSizer( gbSizer2 )
		self.m_panel22.Layout()
		gbSizer2.Fit( self.m_panel22 )
		gbSizer3.Add( self.m_panel22, wx.GBPosition( 0, 0 ), wx.GBSpan( 1, 2 ), wx.EXPAND |wx.ALL, 5 )
		
		self.m_staticText28 = wx.StaticText( self.m_panel20, wx.ID_ANY, u"&P", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.m_staticText28.Wrap( -1 )
		gbSizer3.Add( self.m_staticText28, wx.GBPosition( 1, 0 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )
		
		self.m_textCtrl26 = wx.TextCtrl( self.m_panel20, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
		gbSizer3.Add( self.m_textCtrl26, wx.GBPosition( 1, 1 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )
		
		sbSizer9 = wx.StaticBoxSizer( wx.StaticBox( self.m_panel20, wx.ID_ANY, u"Sizer only" ), wx.HORIZONTAL )
		
		self.m_staticText30 = wx.StaticText( sbSizer9.GetStaticBox(), wx.ID_ANY, u"&Q", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.m_staticText30.Wrap( -1 )
		sbSizer9.Add( self.m_staticText30, 0, wx.ALL, 5 )
		
		self.m_textCtrl27 = wx.TextCtrl( sbSizer9.GetStaticBox(), wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
		sbSizer9.Add( self.m_textCtrl27, 0, wx.ALL, 5 )
		
		
		gbSizer3.Add( sbSizer9, wx.GBPosition( 2, 0 ), wx.GBSpan( 1, 2 ), wx.EXPAND, 5 )
		
		self.m_staticText32 = wx.StaticText( self.m_panel20, wx.ID_ANY, u"&R", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.m_staticText32.Wrap( -1 )
		gbSizer3.Add( self.m_staticText32, wx.GBPosition( 3, 0 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )
		
		self.m_textCtrl29 = wx.TextCtrl( self.m_panel20, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
		gbSizer3.Add( self.m_textCtrl29, wx.GBPosition( 3, 1 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )
		
		sbSizer5 = wx.StaticBoxSizer( wx.StaticBox( self.m_panel20, wx.ID_ANY, u"Sizer + panel + sizer" ), wx.VERTICAL )
		
		self.m_panel23 = wx.Panel( sbSizer5.GetStaticBox(), wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
		self.m_panel23.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
		
		fgSizer5 = wx.FlexGridSizer( 0, 2, 0, 0 )
		fgSizer5.SetFlexibleDirection( wx.BOTH )
		fgSizer5.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
		
		self.m_staticText25 = wx.StaticText( self.m_panel23, wx.ID_ANY, u"&X", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.m_staticText25.Wrap( -1 )
		fgSizer5.Add( self.m_staticText25, 0, wx.ALL, 5 )
		
		self.m_textCtrl23 = wx.TextCtrl( self.m_panel23, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
		fgSizer5.Add( self.m_textCtrl23, 0, wx.ALL, 5 )
		
		self.m_staticText26 = wx.StaticText( self.m_panel23, wx.ID_ANY, u"&Y", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.m_staticText26.Wrap( -1 )
		fgSizer5.Add( self.m_staticText26, 0, wx.ALL, 5 )
		
		self.m_textCtrl24 = wx.TextCtrl( self.m_panel23, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
		fgSizer5.Add( self.m_textCtrl24, 0, wx.ALL, 5 )
		
		self.m_staticText27 = wx.StaticText( self.m_panel23, wx.ID_ANY, u"&Z", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.m_staticText27.Wrap( -1 )
		fgSizer5.Add( self.m_staticText27, 0, wx.ALL, 5 )
		
		self.m_textCtrl25 = wx.TextCtrl( self.m_panel23, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
		fgSizer5.Add( self.m_textCtrl25, 0, wx.ALL, 5 )
		
		
		self.m_panel23.SetSizer( fgSizer5 )
		self.m_panel23.Layout()
		fgSizer5.Fit( self.m_panel23 )
		sbSizer5.Add( self.m_panel23, 1, wx.EXPAND |wx.ALL, 5 )
		
		
		gbSizer3.Add( sbSizer5, wx.GBPosition( 4, 0 ), wx.GBSpan( 1, 2 ), wx.EXPAND, 5 )
		
		
		self.m_panel20.SetSizer( gbSizer3 )
		self.m_panel20.Layout()
		gbSizer3.Fit( self.m_panel20 )
		sbSizer4.Add( self.m_panel20, 1, wx.EXPAND |wx.ALL, 5 )
		
		
		self.SetSizer( sbSizer4 )
		self.Layout()
		
		self.Centre( wx.BOTH )

if __name__ == "__main__":
	app = wx.App(False)
	frame = TestFrame(None)
	frame.Fit()
	frame.Show()
	app.MainLoop()
In this example, you can navigate from "P" and "R" anywhere (by pressing the corresponding Alt+<letter> shortcut), but from "B" and "Q" you'll get nowhere.

Question: How to make the keyboard shortcuts working globally inside a chosen panel?

Post Reply