tags:

views:

199

answers:

2

I have a dialog with a date picker control. Hitting enter in the date picker closes the dialog (as expected). However, the date picker doesn't pick up the value entered by the user on wxGTK. Run the sample attached, click the button, enter a new date in the date picker, using the keyboard, and hit enter. The print statement shows the previous value of the date picker, not the value just entered.

On wxMSW it works as expected. Using wxPython 2.8.10.1 in both cases.

Any ideas? Work-around?

Thanks, Frank

import wx

class Dialog(wx.Dialog):
    def __init__(self, *args, **kwargs):
        super(Dialog, self).__init__(*args, **kwargs)
        self.datepicker = wx.DatePickerCtrl(self)
        self.button = wx.Button(self, label='OK')
        self.button.SetDefault()
        self.button.Bind(wx.EVT_BUTTON, self.onButton)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.datepicker)
        sizer.Add(self.button)
        self.SetSizerAndFit(sizer)

    def onButton(self, event):
        print self.datepicker.GetValue()
        self.Close()


class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(Frame, self).__init__(*args, **kwargs)
        self.button = wx.Button(self, label='Press me to open dialog')
        self.button.Bind(wx.EVT_BUTTON, self.onButton)

    def onButton(self, event):
        dialog = Dialog(self, size=(200,30))
        dialog.Show()   

app = wx.App()
frame = Frame(None, size=(200,50))
frame.Show()
app.MainLoop()
A: 

This seems to work-around the issue:

import wx

class Dialog(wx.Dialog):
    def __init__(self, *args, **kwargs):
        super(Dialog, self).__init__(*args, **kwargs)
        self.datepicker = wx.DatePickerCtrl(self)

        # On wxGTK, intercept all keys:
        if wx.Platform == '__WXGTK__':
            comboCtrl = self.datepicker.GetChildren()[0]
            comboCtrl.Bind(wx.EVT_KEY_DOWN, self.onKey)

        self.button = wx.Button(self, label='OK')
        self.button.SetDefault()
        self.button.Bind(wx.EVT_BUTTON, self.onButton)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.datepicker)
        sizer.Add(self.button)
        self.SetSizerAndFit(sizer)

    def onButton(self, event):
        print self.datepicker.GetValue()
        self.Close()

    def onKey(self, event):
        keyCode = event.GetKeyCode()
        if keyCode == wx.WXK_RETURN:
            # Move to the next field so that the contents of the text control,
            # that might be edited by the user, are updated by the datepicker:
            self.datepicker.Navigate()
            # Next, click the default button of the dialog:
            button = self.GetDefaultItem()
            click = wx.CommandEvent()
            click.SetEventType(wx.EVT_BUTTON.typeId)
            wx.PostEvent(button, click)
        elif keyCode == wx.WXK_TAB:
            self.datepicker.Navigate(not event.ShiftDown())
        else:
            event.Skip()


class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(Frame, self).__init__(*args, **kwargs)
        self.button = wx.Button(self, label='Press me to open dialog')
        self.button.Bind(wx.EVT_BUTTON, self.onButton)

    def onButton(self, event):
        dialog = Dialog(self, size=(200,30))
        dialog.Show()   

app = wx.App()
frame = Frame(None, size=(200,50))
frame.Show()
app.MainLoop()
Frank Niessink
+1  A: 

I had a similar problem. I tried to just call datepicker.Navigate() every time before retrieving the date from the DatePickerCtrl with datepicker.GetValue(). It seemed to work.

Rickard Lindberg
That sure sounds simpler than my work-around, thanks!
Frank Niessink