views:

210

answers:

1

Is it possible to check if a TextCtrl is under keyboard focus (blinking cursor in text box) without defining a handler for EVT_SET_FOCUS?

I just want to do a quick boolean check to prevent a wx.Timer from overwriting the text box if the user is writing something in the box.

+2  A: 

You can bypass a timer update by finding which window has the focus (using FindFocus) and comparing this to your TextCtrl window. Then, if your TextCtrl has the focus you can leave it alone. Here's an example:

import wx

class TestFrame(wx.Frame):

    def __init__(self):
        self.count = 0
        wx.Frame.__init__(self, None, -1, "test frame", size=(200, 100))
        self.panel = wx.Panel(self, -1)
        button = wx.Button(self.panel, -1, "b", pos=(10, 40))
        self.text = wx.TextCtrl(self.panel, -1, `self.count`, size=(50, 25))
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.incr_text)
        self.timer.Start(1000)

    def incr_text(self, event):
        self.count += 1
        f = self.FindFocus()
        if not f==self.text:
            self.text.SetValue(`self.count`)

if __name__=="__main__":
    app = wx.PySimpleApp()
    TestFrame().Show()
    app.MainLoop()
tom10
This worked quite well. Thanks!Instead of "if not f==self.text", I used "if not f in [self.text, self.button_goto]" to make sure the timer didn't overwrite the text box when the user clicked on the "goto" button. I also added a "self.SetFocus()" call in my onGoto method to remove focus from the button once it is clicked.
JcMaco
You're welcome, and I'm glad it worked for you.
tom10
Follow up question: If I include a slider in the GUI and make it behave so that when it is dragged, its current value is displayed in the text box (timer is paused). once the slider is released, the timer can now resume writing text in the textbox. What events can I use to achieve this? My slider is bound to EVT_SLIDER and there doesn't seem to be a way to check the status of the mouse butons with this event.
JcMaco
I don't quite follow. Here are two thoughts: 1) you can use EVT_COMMAND_SCROLL_THUMBRELEASE to indicate when you've released the slider, 2) since you're already using FindFocus to block the timer updates, doesn't it work to just update the timer text box data in the normal way also checking whether the slider has the focus as well?
tom10
According to my tests, when I release the slider the focus is still on the slider. Thus, the timer doesn't update the textbox. Let me try your first thought now.
JcMaco
I added this in my init method: self.components.slider.Bind(wx.EVT_COMMAND_SCROLL_THUMBRELEASE, self.onSliderRelease)onSliderRelease is now just:def onSliderRelease(self,event): self.SetFocus()Thanks again
JcMaco
I get in now... focus stays on the slider unless something else gets the focus. Now that it's solved, one point is that I'm not sure where you're setting the focus, but usually another widget is the safest bet. I'm not sure why, but there are rumors of trouble when setting the focus to frames and panels.
tom10