Eddmik
Eddmik

Reputation: 175

Why in wx.ComboBox wx.EVT_TEXT event is called twice?

In the code, I bind the event self.Bind(wx.EVT_TEXT, self.OnText) to wx.ComboBox. The OnText is called twice. I saw similar behavior with other events too.

My question is:

I saw the following solution:

def OnText(self, event):
    if self.event_skip:
        self.event_skip = False
        return
    do_somthing()
    self.event_skip = True

Upvotes: 1

Views: 1048

Answers (2)

Rolf of Saxony
Rolf of Saxony

Reputation: 22443

Arguably, the answer to your 1st question is Yes!
You are binding to wx.EVT_TEXT rather than the more usual wx.EVT_COMBOBOX, the result I would expect would be an event triggered for each and every text event within that combobox, such as typing or cancelling characters in it.
I suspect, that what you actually want is wx.EVT_TEXT_ENTER which emits an event only when you press the enter key, which would allow you to input a choice not in the choices. To do that you need to have created the combobox with the style=wx.TE_PROCESS_ENTER option.
The events for a combobox are:

EVT_COMBOBOX: Process a wxEVT_COMBOBOX event, when an item on the list is selected. Note that calling GetValue returns the new value of selection.
EVT_TEXT: Process a wxEVT_TEXT event, when the combobox text changes.
EVT_TEXT_ENTER: Process a wxEVT_TEXT_ENTER event, when RETURN is pressed in the combobox (notice that the combobox must have been created with wx.TE_PROCESS_ENTER style to receive this event).
EVT_COMBOBOX_DROPDOWN: Process a wxEVT_COMBOBOX_DROPDOWN event, which is generated when the list box part of the combo box is shown (drops down). Notice that this event is only supported by wxMSW, wxGTK with GTK+ 2.10 or later, and OSX/Cocoa.
EVT_COMBOBOX_CLOSEUP: Process a wxEVT_COMBOBOX_CLOSEUP event, which is generated when the list box of the combo box disappears (closes up). This event is only generated for the same platforms as wxEVT_COMBOBOX_DROPDOWN above. Also note that only wxMSW and OSX/Cocoa support adding or deleting items in this event.

Edit: I had a look at the code you referenced in a comment to the other answer. It is slightly confusing because it refers to self.ignoreEvtText, which make it look as if it is in some way related to either the event or EVT_TEXT.
It isn't! The coder set that variable up themselves,

self.Bind(wx.EVT_TEXT, self.EvtText)
self.Bind(wx.EVT_CHAR, self.EvtChar)
self.Bind(wx.EVT_COMBOBOX, self.EvtCombobox)
self.ignoreEvtText = False

and is using it to manipulate what happens because they bound 3 events to the same combobox.
If the user selects an item from choices wx.EVT_COMBOBOX or if the user presses back tab (keycode 8) wx.EVT_CHAR, the wx.EVT_TEXT events are ignored.
I hope that clarifies things a bit.

Upvotes: 4

Jan
Jan

Reputation: 952

I don't think that getting two events is the expected behavior. I constructed a minimal working example of a wx.TextCtrl, and whatever I tried, a single change of the content of this control fired up only one wx.EVT_TEXT event for me, not two:

import time
import wx

def evthandler(evt):
    print(time.time())

if __name__ == "__main__":
    app = wx.App()
    frame = wx.Frame(None)
    text = wx.TextCtrl(frame)
    text.Bind(wx.EVT_TEXT, evthandler)
    frame.Show()
    app.MainLoop()

Upvotes: 0

Related Questions