[wxPython-users] Re: ComboBox: Incorrect usage?
Frank Millman
frank at chagford.com
Thu Jul 26 22:44:11 PDT 2007
Steve Holden wrote:
> Thanks, that's a win. I'll let the list know if I make any
> progress on this - I suspect I may need to create something
> like a pop-up pull-down list to do this properly.
>
FYI, I had some success with a customised ComboCtrl, which I got to emulate
a wx.Choice but with some additional features. Maybe you could do something
similar. Attached is a program that shows what I did.
Frank
-------------- next part --------------
#!/usr/bin/env python
import sys
import wx
import wx.combo
class MyChoice(wx.combo.ComboCtrl):
def __init__(self,parent,choices,selection,size,pos):
wx.combo.ComboCtrl.__init__(self,parent,size=size,pos=pos)
MyComboPopup(self,choices,selection)
self.textCtrl = self.GetTextCtrl()
self.textCtrl.Bind(wx.EVT_SET_FOCUS,self.onGotFocus)
self.textCtrl.Bind(wx.EVT_KILL_FOCUS,self.onLostFocus)
self.count = 0
self.nav = False
def onGotFocus(self,evt):
self.count += 1
print self.count,'got focus'
if self.nav:
self.nav = False
wx.CallAfter(self.Navigate)
evt.Skip()
def onLostFocus(self,evt):
print self.count,'lost focus'
self.textCtrl.SetSelection(0,0)
evt.Skip()
class MyComboPopup(wx.ListBox, wx.combo.ComboPopup):
def __init__(self,comboCtrl,choices,selection):
self.comboCtrl = comboCtrl
self.choices = choices
self.curitem = self.selection = selection
wx.combo.ComboPopup.__init__(self)
comboCtrl.SetPopupControl(self)
comboCtrl.SetValue(choices[selection])
def Create(self, parent):
# Create the popup child control. Return true for success.
self.listBox = wx.ListBox(parent,choices=self.choices)
self.listBox.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self.listBox.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
return True
def OnKeyDown(self, evt):
if evt.KeyCode == wx.WXK_DOWN:
if self.curitem < len(self.choices)-1:
self.curitem += 1
self.listBox.Select(self.curitem)
return
if evt.KeyCode == wx.WXK_UP:
if self.curitem > 0:
self.curitem -= 1
self.listBox.Select(self.curitem)
return
if evt.KeyCode == wx.WXK_ESCAPE:
self.Dismiss()
return
if evt.KeyCode in (wx.WXK_TAB,wx.WXK_SPACE,wx.WXK_RETURN,wx.WXK_NUMPAD_ENTER):
self.selection = self.curitem
self.comboCtrl.nav = True
self.Dismiss()
return
def OnLeftDown(self, evt):
item = self.listBox.HitTest(evt.GetPosition())
if item > -1:
self.selection = item
self.Dismiss()
def GetControl(self):
# Return the widget that is to be used for the popup
return self.listBox
def GetStringValue(self):
# Return a string representation of the current item.
return self.choices[self.selection]
def OnPopup(self):
# Called immediately after the popup is shown
print 'popup'
self.curitem = self.selection
self.listBox.Select(self.selection)
wx.combo.ComboPopup.OnPopup(self)
def OnDismiss(self):
# Called when popup is dismissed
print 'dismiss'
wx.combo.ComboPopup.OnDismiss(self)
def OnComboKeyEvent(self, evt):
# Receives key events from the parent ComboCtrl. Events not
# handled should be skipped, as usual.
if evt.KeyCode == wx.WXK_SPACE:
self.comboCtrl.ShowPopup()
elif evt.KeyCode == wx.WXK_DOWN:
if self.selection < len(self.choices)-1:
self.selection += 1
self.comboCtrl.SetValue(self.choices[self.selection])
self.comboCtrl.GetTextCtrl().SetSelection(-1,-1)
elif evt.KeyCode == wx.WXK_UP:
if self.selection > 0:
self.selection -= 1
self.comboCtrl.SetValue(self.choices[self.selection])
self.comboCtrl.GetTextCtrl().SetSelection(-1,-1)
def GetAdjustedSize(self, minWidth, prefHeight, maxHeight):
# Return final size of popup. Called on every popup, just prior to OnPopup.
# minWidth = preferred minimum width for window
# prefHeight = preferred height. Only applies if > 0,
# maxHeight = max height for window, as limited by screen size
# and should only be rounded down, if necessary.
if sys.platform == 'win32':
prefHeight = 15 * len(self.choices)
else:
prefHeight = 26 * len(self.choices)
return wx.combo.ComboPopup.GetAdjustedSize(self, minWidth, prefHeight, maxHeight)
class MyPanel(wx.Panel):
def __init__(self,parent):
wx.Panel.__init__(self,parent,-1)
choices = ['Category 1','Category 2','Category 3']
selection = 1
wx.StaticText(self,-1,'Field1',pos=(50,30))
wx.TextCtrl(self,-1,'',size=(180,-1),pos=(150,30))
wx.StaticText(self,-1,'Field2',pos=(50,80))
MyChoice(self,choices,selection,size=(180,-1),pos=(150,80))
wx.StaticText(self,-1,'Field3',pos=(50,130))
wx.TextCtrl(self,-1,'',size=(180,-1),pos=(150,130))
self.SetFocus()
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,-1,"Custom ComboCtrl test",size=(400,200))
panel = MyPanel(self)
self.CentreOnScreen()
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame()
frame.Show(1)
return 1
app = MyApp(0)
app.MainLoop()
More information about the wxpython-users
mailing list