jpf
jpf

Reputation: 1475

wxPython Unbind method returns True but doesn't Unbind

I am trying to Unbind the event wx.EVT_LEFT_DOWN from a TextCtrl window either

  1. the first time the user clicks inside the text field, or
  2. with the first character entered in the text field.

My initial attempt at (1.) failed (see commented code below) when I attempted an Unbind inside the method to which the event was bound. The TextCtrl field no longer allowed any text entry.

The attempt at (2.) is shown below, but does not produce the desired behavior even though I've tested the return value of the Unbind and it is True.

The desired behavior is that, the first time the user clicks in the window (TextCtrl), the default text should be cleared, but, once the user has entered text and clicks again in the window, the text entered should not be cleared. How can I achieve the desired behavior with the Unbind method?

I can think of other ways (e.g. count the number of times the user clicks inside the window and only clear the text if it is the first time), but these are less clean.

import wx

class FormTab(wx.Panel):

  def __init__(self, *args, **kwargs):
    super(FormTab, self).__init__(*args, **kwargs)
    self.createControls()
    self.bindEvents()
    self.doLayout()

  def createControls(self):
    self.exeTextCtrl = wx.TextCtrl(self, value="Executable")
    font=wx.Font(8,wx.DEFAULT,wx.ITALIC,wx.NORMAL)
    self.exeTextCtrl.SetFont(font)

  def bindEvents(self):
    for control, event, handler in \
      [(self.exeTextCtrl, wx.EVT_LEFT_DOWN, self.onExeReady),
       (self.exeTextCtrl, wx.EVT_TEXT, self.onExeEntered)]:
      control.Bind(event, handler)

  def onExeReady(self, event):
    self.exeTextCtrl.SetValue('')
    font=wx.Font(8,wx.DEFAULT,wx.NORMAL,wx.NORMAL)
    self.exeTextCtrl.SetFont(font)
# (1) attempt failed and made text field inoperable
#   self.exeTextCtrl.Unbind(wx.EVT_LEFT_DOWN, self.onExeReady)
    event.Skip()

  def onExeEntered(self, event):
    font=wx.Font(8,wx.DEFAULT,wx.NORMAL,wx.NORMAL)
    self.exeTextCtrl.SetFont(font)
    exclass.exe=event.GetString()
# (2) attempt doesn't unbind event (even though following returns True)
    self.exeTextCtrl.Unbind(wx.EVT_LEFT_DOWN, self.onExeReady)

# etc...

Thank you.

Upvotes: 2

Views: 2600

Answers (1)

nepix32
nepix32

Reputation: 3177

From wx._core:

class EvtHandler(Object):
    """Proxy of C++ EvtHandler class"""

    ...

    def Unbind(self, event, source=None, id=wx.ID_ANY, id2=wx.ID_ANY, handler=None):
        """
        Disconnects the event handler binding for event from self.
        Returns True if successful.
        """

In your example, change:

self.exeTextCtrl.Unbind(wx.EVT_LEFT_DOWN, self.onExeReady)

which leads to a AttributeError: 'function' object has no attribute 'GetId' (because you specified the handler self.onExeReady instead of a source parameter), to:

self.exeTextCtrl.Unbind(wx.EVT_LEFT_DOWN)

Admittedly, none of the following did work (did not work and returned False):

self.Unbind(wx.EVT_LEFT_DOWN, source=self.exeTextCtrl)
self.exeTextCtrl.Unbind(wx.EVT_LEFT_DOWN, self.exeTextCtrl)
self.exeTextCtrl.Unbind(wx.EVT_LEFT_DOWN, source=self.exeTextCtrl, handler=self.onExeReady)

Hope that helps.

Upvotes: 2

Related Questions