hello.
I have been working all too hard trying to figure out how to get
TextCtrlAutoCom plete.py to start another word after it finishes the
last word. I want it to start the autocomplete process all over again
after it finishes the autocomplete process. I have striped down the
program to a smaller version than the orginal. it now works in a
multiline wx.textctrl box. belive that the program only needs one or
two lines to complete the taks and start all over again.
here is a copy of the code
'''
wxPython Custom Widget Collection 20060207
Written By: Edward Flick ()
Michele Petrazzo (michele -=dot=- petrazzo -=at=- unipex
-=dot=- it)
Will Sadkin (wsadkin-=at=- nameconnector -=dot=- com)
Copyright 2006 (c) CDF Inc. ( http://www.cdf-imaging.com )
Contributed to the wxPython project under the wxPython project's
license.
'''
import wx
import sys
import wx.lib.mixins.l istctrl as listmix
class myListCtrl(wx.L istCtrl, listmix.ListCtr lAutoWidthMixin ):
def __init__(self,
parent,
ID=-1,
pos=wx.DefaultP osition,
size=wx.Default Size,
style=0):
wx.ListCtrl.__i nit__(self, parent, ID, pos, size, style)
listmix.ListCtr lAutoWidthMixin .__init__(self)
class TextCtrlAutoCom plete (wx.TextCtrl, listmix.ColumnS orterMixin ):
def __init__ ( self, parent, choices = None,
showHead=False, dropDownClick=T rue,
colFetch=-1, colSearch=0, hideOnNoMatch=T rue,
selectCallback= None, entryCallback=N one,
matchFunction=N one,
**therest) :
'''
Constructor works just like wx.TextCtrl except you can pass in
a
list of choices. You can also change the choice list at any
time
by calling setChoices.
'''
if therest.has_key ('style'):
therest['style']=wx.TE_PROCESS_ ENTER | therest['style']
else:
therest['style']=wx.TE_PROCESS_ ENTER
wx.TextCtrl.__i nit__(self,pare nt,-1,'',size=(500, 500),style=wx.T E_MULTILINE)
#wx.TextCtrl.__ init__(self, parent, **therest )
self._hideOnNoM atch = hideOnNoMatch
self._selectCal lback = selectCallback
self._matchFunc tion = matchFunction
self._screenhei ght = wx.SystemSettin gs.GetMetric(
wx.SYS_SCREEN_Y )
#sort variable needed by listmix
self.itemDataMa p = dict()
#widgets
self.dropdown = wx.PopupWindow( self )
#Control the style
flags = wx.LC_REPORT | wx.LC_SINGLE_SE L | wx.LC_SORT_ASCE NDING
if not (showHead) :
flags = flags | wx.LC_NO_HEADER
#Create the list and bind the events
self.dropdownli stbox = myListCtrl( self.dropdown, style=flags,
pos=wx.Point( 0, 0) )
gp = self
while ( gp != None ) :
gp = gp.GetParent()
self.Bind( wx.EVT_TEXT , self.onEnteredT ext, self )
self.Bind( wx.EVT_KEY_DOWN , self.onKeyDown, self )
self.dropdownli stbox.Bind(wx.E VT_LEFT_DCLICK,
self.onListDCli ck)
def onListDClick(se lf, evt):
self._setValueF romSelected()
def onEnteredText(s elf, event):
text = event.GetString ()
#print('onEnter dText text: ',text)
if self._entryCall back:
self._entryCall back()
if not text:
# control is empty; hide dropdown if shown:
if self.dropdown.I sShown():
self._showDropD own(False)
event.Skip()
return
found = False
choices = self._choices
for numCh, choice in enumerate(choic es):
if self._matchFunc tion and self._matchFunc tion(text,
choice):
found = True
elif choice.lower(). startswith(text .lower()) :
found = True
if found:
self._showDropD own(True)
item = self.dropdownli stbox.GetItem(n umCh)
toSel = item.GetId()
self.dropdownli stbox.Select(to Sel)
break
if not found:
self.dropdownli stbox.Select(se lf.dropdownlist box.GetFirstSel ected(),
False)
if self._hideOnNoM atch:
self._showDropD own(False)
self._listItemV isible()
event.Skip ()
def onKeyDown ( self, event ) :
""" Do some work when the user press on the keys:
up and down: move the cursor
left and right: move the search
"""
skip = True
sel = self.dropdownli stbox.GetFirstS elected()
visible = self.dropdown.I sShown()
KC = event.GetKeyCod e()
if KC == wx.WXK_DOWN :
if sel < (self.dropdownl istbox.GetItemC ount () - 1) :
self.dropdownli stbox.Select ( sel+1 )
self._listItemV isible()
self._showDropD own ()
skip = False
elif KC == wx.WXK_UP :
if sel > 0 :
self.dropdownli stbox.Select ( sel - 1 )
self._listItemV isible()
self._showDropD own ()
skip = False
if visible :
if event.GetKeyCod e() == wx.WXK_RETURN :
self._setValueF romSelected()
skip = False
if event.GetKeyCod e() == wx.WXK_ESCAPE :
self._showDropD own( False )
skip = False
if skip :
event.Skip()
def onListItemSelec ted (self, event):
self._setValueF romSelected()
event.Skip()
def onClickToggleDo wn(self, event):
self._lastinser tionpoint = self.GetInserti onPoint()
event.Skip ()
def onClickToggleUp ( self, event ) :
if ( self.GetInserti onPoint() == self._lastinser tionpoint ) :
self._showDropD own ( not self.dropdown.I sShown() )
event.Skip ()
# -- Interfaces methods
def SetChoices(self , choices):
#Sets the choices available in the popup wx.ListBox.
#The items will be sorted case insensitively.
self._choices = choices
flags = wx.LC_REPORT | wx.LC_SINGLE_SE L | wx.LC_SORT_ASCE NDING
| wx.LC_NO_HEADER
self._updateDat aList(self._cho ices)
self.dropdownli stbox.InsertCol umn(0, "")
for num, colVal in enumerate(self. _choices):
index =
self.dropdownli stbox.InsertIma geStringItem(sy s.maxint, colVal, -1)
self.dropdownli stbox.SetString Item(index, 0, colVal)
self.dropdownli stbox.SetItemDa ta(index, num)
self._setListSi ze()
# there is only one choice for both search and fetch if setting
a single column:
self._colSearch = 0
self._colFetch = -1
def SetSelectCallba ck(self, cb=None):
self._selectCal lback = cb
def SetEntryCallbac k(self, cb=None):
self._entryCall back = cb
#-- Internal methods
def _setValueFromSe lected( self ) :
'''
Sets the wx.TextCtrl value from the selected wx.ListCtrl item.
Will do nothing if no item is selected in the wx.ListCtrl.
'''
sel = self.dropdownli stbox.GetFirstS elected()
if sel > -1:
if self._colFetch != -1: col = self._colFetch
else: col = self._colSearch
itemtext = self.dropdownli stbox.GetItem(s el, col).GetText()
if self._selectCal lback:
dd = self.dropdownli stbox
values = [dd.GetItem(sel, x).GetText()
for x in xrange(dd.GetCo lumnCount())]
self._selectCal lback( values )
self.SetValue (itemtext)
self.SetInserti onPointEnd ()
self.SetSelecti on ( -1, -1 )
self._showDropD own ( False )
def _showDropDown ( self, show = True ) :
'''
Either display the drop down list (show = True) or hide it
(show = False).
'''
if show :
size = self.dropdown.G etSize()
width, height = self . GetSizeTuple()
x, y = self . ClientToScreenX Y ( wx.CentreX+6, wx.CentreY+6
)
if size.GetWidth() != width :
size.SetWidth(w idth)
self.dropdown.S etSize(size)
self.dropdownli stbox.SetSize(s elf.dropdown.Ge tClientSize())
if (y + size.GetHeight( )) < self._screenhei ght :
self.dropdown . SetPosition ( wx.Point(x, y) )
else:
self.dropdown . SetPosition ( wx.Point(x, y - height -
size.GetHeight( )) )
self.dropdown.S how ( show )
def _listItemVisibl e( self ) :
'''
Moves the selected item to the top of the list ensuring it is
always visible.
'''
toSel = self.dropdownli stbox.GetFirstS elected ()
if toSel == -1: return
self.dropdownli stbox.EnsureVis ible( toSel )
def _updateDataList (self, choices):
#delete, if need, all the previous data
if self.dropdownli stbox.GetColumn Count() != 0:
self.dropdownli stbox.DeleteAll Columns()
self.dropdownli stbox.DeleteAll Items()
#and update the dict
if choices:
for numVal, data in enumerate(choic es):
self.itemDataMa p[numVal] = data
#print("data is %s",data)
else:
numVal = 0
self.SetColumnC ount(numVal)
def _setListSize(se lf):
choices = self._choices
longest = 0
for choice in choices :
longest = max(len(choice) , longest)
#longest += 3
itemcount = min( len( choices ) , 7 ) + .5
charheight = self.dropdownli stbox.GetCharHe ight()
charwidth = self.dropdownli stbox.GetCharWi dth()
self.popupsize = wx.Size( charwidth*longe st,
charheight*item count )
self.dropdownli stbox.SetSize ( self.popupsize )
self.dropdown.S etClientSize( self.popupsize )
class test:
def __init__(self):
args = dict()
args["selectCallback "] = self.selectCall back
self.dynamic_ch oices = [
'hello world', 'abandon', 'acorn', 'acute',
'adore',
'aegis', 'ascertain', 'asteroid',
'beautiful', 'bold', 'classic',
'daring', 'dazzling', 'debonair', 'definitive',
'effective', 'elegant',
'http://python.org', 'http://www.google.com' ,
'fabulous', 'fantastic', 'friendly',
'forgiving', 'feature',
'sage', 'scarlet', 'scenic', 'seaside',
'showpiece', 'spiffy',
'www.wxPython.o rg', 'www.osafoundat ion.org'
]
app = wx.PySimpleApp( )
frm = wx.Frame(None,-1,"Test",
style=wx.CLEAR
|wx.DEFAULT_FRA ME_STYLE
)
panel = wx.Panel(frm)
self._ctrl = TextCtrlAutoCom plete(panel, **args)
self.onBtDynami cChoices(self.o nBtDynamicChoic es)
frm.Show()
app.MainLoop()
def onBtDynamicChoi ces(self, event):
self._ctrl.SetC hoices(self.dyn amic_choices)
self._ctrl.SetE ntryCallback(se lf.setDynamicCh oices)
def match(self, text, choice):
t = text.lower()
c = choice.lower()
#print('The Value is %S',choice)
return c.startswith(t)
def setDynamicChoic es(self):
if wx.EVT_KEY_DOWN == ' ': print "Space bar pressed"
text = self._ctrl.GetV alue().lower()
choices = [choice for choice in self.dynamic_ch oices if
self.match(text , choice)]
self._ctrl.SetC hoices(choices)
#print('The Value is %S',text)
def selectCallback( self, values):
""" Simply function that receive the row values when the
user select an item
"""
print "Select Callback called...:", values
self.wordCheck( values)
def wordCheck(self, values):
pass #print"Word to check:",values
if __name__ == "__main__":
test()