Reputation: 11
When assigning the value to combobox in event it will fire again same event and program goes in infinite loop. however same code working in wxpython version 4.0.7. correct me if I am doing something wrong.
import wx
class Mywin(wx.Frame):
def __init__(self, parent: object, title: object) -> object:
super(Mywin, self).__init__(parent, title=title, size=(300, 200))
self.languages = ['C', 'C++', 'Python', 'Java', 'Perl']
panel = wx.Panel(self)
box = wx.BoxSizer(wx.VERTICAL)
self.label = wx.StaticText(panel, label="Your choice:", style=wx.ALIGN_CENTRE)
box.Add(self.label, 0, wx.EXPAND | wx.ALL, 20)
cblbl = wx.StaticText(panel, label="Combo box", style=wx.ALIGN_CENTRE)
box.Add(cblbl, 0, wx.EXPAND | wx.ALL, 5)
self.combo = wx.ComboBox(panel, choices=self.languages)
box.Add(self.combo, 1, wx.EXPAND | wx.ALL, 5)
box.AddStretchSpacer()
self.combo.Bind(wx.EVT_TEXT, self.oncombo)
self.ignoreEvtText = False
panel.SetSizer(box)
self.Centre()
self.Show()
def oncombo(self, event):
if self.ignoreEvtText:
self.ignoreEvtText = False
return
textEntered = event.GetString()
self.label.SetLabel("You selected" + self.combo.GetValue() + " from Combobox" + textEntered)
if textEntered:
self.ignoreEvtText = True
matching = [s for s in self.languages if textEntered in s]
self.combo.Set(matching)
self.combo.SetInsertionPoint(len(textEntered))
self.combo.SetValue(textEntered)
else:
self.combo.Set(self.languages)
self.combo.Popup()
app = wx.App()
Mywin(None, 'ComboBox and Choice demo')
app.MainLoop()
Upvotes: 0
Views: 141
Reputation: 3649
I couldn't find a clear answer regarding the infinite loop anywhere else so I did a little investigation of my own.
It appears that an EVT_TEXT
is fired as a result of the call to Set
as well the call to SetValue
. This means that you have to do:
self.ignoreEvtText = True
self.Set(matching)
self.ignoreEvtText = True
self.SetValue(textEntered)
self.combo.SetInsertionPoint(len(textEntered))
to avoid creating the infinite loop of events. The call to SetInsertionPoint
has to move after the call to SetValue
also, otherwise the text isn't there for the insertion point to be set correctly.
As a final note the call to Popup
causes very odd results, at least for me on the latest wxPython on Windows 11. In particular, an annoying delay after each character while the dropdown animation plays again, and the text being highlighted and then immediately un-highlighted. Additionally there were cases where losing focus would cause the dropdown to go into a disappear-reappear loop drawn on top of the application that now had focus. As a result I've ended up not using that. The user can open the dropdown themself and avoid the weirdness.
Upvotes: 0
Reputation: 22448
Use:
self.combo.Bind(wx.EVT_COMBOBOX, self.oncombo)
rather than:
self.combo.Bind(wx.EVT_TEXT, self.oncombo)
EVT_TEXT causes you to drop into an continual event loop.
Each time the text changes, if fires the event, which changes the text, which fires the event, which ......
Upvotes: 0