问题
I built a gui using wx.glade. Part of this gui is a section to enter in passwords and then click a button to validate them. To make this section I used a grid sizer. Not every cell of the grid needed to have a button or field in it, so I filled these with wx.panel components as spacers.
What happens is that as I tab through the tx fields and buttons everything is fine, but the wx.panel spacers are also part of that tab list. What I want to do is make them non-tab selectable.
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
# begin wxGlade: mainFrame.__init__
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.panelLower = wx.Panel(self, -1)
self.panelUpper = wx.Panel(self, -1)
self.sizerPassword_staticbox = wx.StaticBox(self.panelLower, -1, "Password Settings")
self.sizerInstall_staticbox = wx.StaticBox(self.panelLower, -1, "Install Actions")
self.sizerStatus_staticbox = wx.StaticBox(self.panelUpper, -1, "Status")
self.mainStatusbar = self.CreateStatusBar(1, 0)
#Status List
self.statusListCtrl = wx.ListCtrl(self.panelUpper, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
self._init_coll_statusListCtrl_Columns(self.statusListCtrl)
#Password Settings
self.stInfraSystem = wx.StaticText(self.panelLower, -1, "infra.system")
self.txInfraSystem = wx.TextCtrl(self.panelLower, -1, "Enter Password")
self.btnInfraSystem = wx.Button(self.panelLower, -1, "Validate")
self.stIwpcSystem = wx.StaticText(self.panelLower, -1, "iwpc.system")
self.txIwpcSystem = wx.TextCtrl(self.panelLower, -1, "Enter Password")
self.btnIwpcSystem = wx.Button(self.panelLower, -1, "Validate")
self.stIwpcIwpcdba = wx.StaticText(self.panelLower, -1, "iwpc.iwpcdba")
self.txIwpcIwpcdba = wx.TextCtrl(self.panelLower, -1, "Enter Password")
self.btnIwpcIwpcdba = wx.Button(self.panelLower, -1, "Validate")
self.stLdapOc4jadmin = wx.StaticText(self.panelLower, -1, "ldap.oc4jadmin")
self.txLdapOc4jadmin = wx.TextCtrl(self.panelLower, -1, "Enter Password")
self.btnLdapOc4jadmin = wx.Button(self.panelLower, -1, "Validate")
self.stLdapOrcladmin = wx.StaticText(self.panelLower, -1, "ldap.orcladmin")
self.txLdapOrcladmin = wx.TextCtrl(self.panelLower, -1, "Enter Password")
self.btnLdapOrcladmin = wx.Button(self.panelLower, -1, "Validate")
self.stIasAdmin = wx.StaticText(self.panelLower, -1, "ias_admin")
self.txIasAdmin = wx.TextCtrl(self.panelLower, -1, "Enter Password")
self.btnIasAdmin = wx.Button(self.panelLower, -1, "Validate")
self.stIwpcadmin = wx.StaticText(self.panelLower, -1, "iwpcadmin")
self.txIwpcadmin = wx.TextCtrl(self.panelLower, -1, "Enter Password")
self.btnIwpcadmin = wx.Button(self.panelLower, -1, "Validate")
self.panel_1 = wx.Panel(self.panelLower, -1)
self.panel_2 = wx.Panel(self.panelLower, -1)
self.btnValidateAll = wx.Button(self.panelLower, -1, "Validate All")
#Install Actions
##SSp List
self.olvSSP = ObjectListView(self.panelLower, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
#olvColumns = ColumnDefn("Available SSPs", "left", 200, valueGetter="name")
#self.olvSSP.SetColumn(olvColumns)
self._init_coll_olvSSP_Columns()
self.olvSSP.CreateCheckStateColumn()
self.installSpacer0 = wx.Panel(self.panelLower, -1)
self.installSpacer1 = wx.Panel(self.panelLower, -1)
self.installSpacer2 = wx.Panel(self.panelLower, -1)
self.installSpacer3 = wx.Panel(self.panelLower, -1)
self.installSpacer4 = wx.Panel(self.panelLower, -1)
self.panel_8 = wx.Panel(self.panelLower, -1)
self.panel_9 = wx.Panel(self.panelLower, -1)
self.btnBeginInstall = wx.Button(self.panelLower, -1, "Begin Install")
self.__set_properties()
self.__do_layout()
self.Bind(wx.EVT_BUTTON, self.onBtValidateInfraSystem, self.btnInfraSystem)
self.Bind(wx.EVT_BUTTON, self.onBtValidateIwpcSystem, self.btnIwpcSystem)
self.Bind(wx.EVT_BUTTON, self.onBtValidateIwpcIwpcdba, self.btnIwpcIwpcdba)
self.Bind(wx.EVT_BUTTON, self.onBtValidateLdapOc4jadmin, self.btnLdapOc4jadmin)
self.Bind(wx.EVT_BUTTON, self.onBtValidateLdapOrcladmin, self.btnLdapOrcladmin)
self.Bind(wx.EVT_BUTTON, self.onBtValidateIasAdmin, self.btnIasAdmin)
self.Bind(wx.EVT_BUTTON, self.onBtValidateIwpcadmin, self.btnIwpcadmin)
self.Bind(wx.EVT_BUTTON, self.onBtValidateAll, self.btnValidateAll)
self.Bind(wx.EVT_BUTTON, self.onBtBeginInstall, self.btnBeginInstall)
# end wxGlade
def _init_coll_statusListCtrl_Columns(self, parent):
# generated method, don't edit
parent.InsertColumn(col=0, format=wx.LIST_FORMAT_LEFT,
heading=u'Timestamp', width=200)
parent.InsertColumn(col=1, format=wx.LIST_FORMAT_LEFT,
heading=u'Action', width=200)
parent.InsertColumn(col=2, format=wx.LIST_FORMAT_LEFT,
heading=u'Result', width=400)
def _init_coll_olvSSP_Columns(self, data=None):
self.olvSSP.SetColumns([
ColumnDefn("Available SSPs", "left", 200, "name"),
])
def __set_properties(self):
# begin wxGlade: mainFrame.__set_properties
self.SetTitle("SSP Installer")
self.mainStatusbar.SetStatusWidths([-1])
# statusbar fields
mainStatusbar_fields = ["MyFrame_statusbar"]
for i in range(len(mainStatusbar_fields)):
self.mainStatusbar.SetStatusText(mainStatusbar_fields[i], i)
# end wxGlade
def __do_layout(self):
# begin wxGlade: mainFrame.__do_layout
mainSizer = wx.GridSizer(2, 1, 0, 0)
sizerLower = wx.GridSizer(1, 2, 0, 0)
sizerInstall = wx.StaticBoxSizer(self.sizerInstall_staticbox, wx.HORIZONTAL)
sizerInstallButtons = wx.GridSizer(1, 2, 0, 0)
sizer_4 = wx.BoxSizer(wx.VERTICAL)
sizerPassword = wx.StaticBoxSizer(self.sizerPassword_staticbox, wx.HORIZONTAL)
grid_sizer_1 = wx.GridSizer(8, 3, 0, 0)
sizerStatus = wx.StaticBoxSizer(self.sizerStatus_staticbox, wx.VERTICAL)
sizerStatus.Add(self.statusListCtrl, 1, wx.ALL|wx.EXPAND, 2)
self.panelUpper.SetSizer(sizerStatus)
mainSizer.Add(self.panelUpper, 1, wx.EXPAND, 0)
grid_sizer_1.Add(self.stInfraSystem, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.txInfraSystem, 1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.btnInfraSystem, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.stIwpcSystem, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.txIwpcSystem, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.btnIwpcSystem, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.stIwpcIwpcdba, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.txIwpcIwpcdba, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.btnIwpcIwpcdba, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.stLdapOc4jadmin, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.txLdapOc4jadmin, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.btnLdapOc4jadmin, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.stLdapOrcladmin, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.txLdapOrcladmin, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.btnLdapOrcladmin, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.stIasAdmin, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.txIasAdmin, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.btnIasAdmin, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.stIwpcadmin, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.txIwpcadmin, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.btnIwpcadmin, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
grid_sizer_1.Add(self.panel_1, 1, wx.EXPAND, 0)
grid_sizer_1.Add(self.panel_2, 1, wx.EXPAND, 0)
grid_sizer_1.Add(self.btnValidateAll, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
sizerPassword.Add(grid_sizer_1, 1, wx.EXPAND, 0)
sizerLower.Add(sizerPassword, 1, wx.EXPAND, 0)
sizerInstallButtons.Add(self.olvSSP, 1, wx.ALL|wx.EXPAND, 2)
sizer_4.Add(self.installSpacer0, 1, wx.EXPAND, 0)
sizer_4.Add(self.installSpacer1, 1, wx.EXPAND, 0)
sizer_4.Add(self.installSpacer2, 1, wx.EXPAND, 0)
sizer_4.Add(self.installSpacer3, 1, wx.EXPAND, 0)
sizer_4.Add(self.installSpacer4, 1, wx.EXPAND, 0)
sizer_4.Add(self.panel_8, 1, wx.EXPAND, 0)
sizer_4.Add(self.panel_9, 1, wx.EXPAND, 0)
sizer_4.Add(self.btnBeginInstall, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 2)
sizerInstallButtons.Add(sizer_4, 1, wx.EXPAND, 0)
sizerInstall.Add(sizerInstallButtons, 1, wx.EXPAND, 0)
sizerLower.Add(sizerInstall, 1, wx.EXPAND, 0)
self.panelLower.SetSizer(sizerLower)
mainSizer.Add(self.panelLower, 1, wx.EXPAND, 0)
self.SetSizer(mainSizer)
mainSizer.Fit(self)
self.Layout()
# end wxGlade
回答1:
Panels usually don't accept focus per se, so that's a little odd. You can catch the focus event and tell it to set focus on the next widget instead, assuming you keep track of tab order yourself. Or you can try disabling the panels, which should have the same effect.
回答2:
Maybe I'm misunderstanding you but why not just use a spacer? They seem to be designed precisely for this purpose and won't accept tabs...wxglade has a button for them and they evaluate to:
sizer.add((20,20) 1, wx.EXPAND, 0)
20x20 is the nominal size of the spacer in pixels but you can apply the usual set of flags to adjust resize behaviour.
来源:https://stackoverflow.com/questions/5818592/wxpython-making-a-panel-not-accessible-through-tab