A wx.DatePickerCtrl with a customisable format

I really do think, this is an issue in wx.adv.GenericCalendarCtrl, of course I could be horribly wrong.
Could you lift the 2nd piece of code written by RichardT at:

and tell me if that works, just to test it using code written by some one else. (Cheers Richard)
I don’t have access to MS Windows, so I can’t replicate your problem.

The code is identical, I think, to minidatepicker.py which also calls wx.adv.GenericCalendarCtrl in a wx.PopupTransientWindow, so I would expect that to fail as well, if there’s a bug.

For the record I code on Linux Mint 20.3 - Python 3.8.10 - wxPython 4.2.1 gtk3 (phoenix) wxWidgets 3.2.2.1

Regards,
Rolf

Hi,
I will try it, but let me tell you, the wx.adv.GenericCalendarCtrl works correctly in wxdemo in my system.

Hello Rolf,
Excellent bit of code. I am also experiencing the same issue as steve2, unfortunately. Any insight?

Good evening Rushin,

As I explained, I don’t have access to the Windows operating system and currently. I’m convinced it’s an issue with wx.adv.GenericCalendarCtrl or how I’m handling it, which doesn’t reveal itself on Linux.
My reasoning: that month selection process is within wx.adv.GenericCalendarCtrl not my code.

So I’m rather hoping that someone who does run Windows can get to the bottom of it or at least, report back if the 2 pieces of code I mentioned above, also fail or work without a glitch.

That would at least allow me to go through the code looking for any form of difference in the way I utilise wx.adv.GenericCalendarCtrl, within minidatepickerbutton.py

1 Like

Hi Rolf,

wx.adv.GenericCalendarCtrl works fine in wxpython demo (Windows 10, python 3.11.4, wxpython 4.2.1). Therefore I don’t think that wx.adv.GenericCalendarCtrl is buggy.

Morning Steve,
That isn’t really what I proposed, as I’d expect the demo to function, but it is what it is.

Try changing the method of month/year selection in the DemoFrame class to:

self.mdb.SetCalendarStyle(wx.adv.CAL_SHOW_WEEK_NUMBERS|wx.adv.CAL_MONDAY_FIRST|wx.adv.CAL_SEQUENTIAL_MONTH_SELECTION)

See if it behaves itself.

Screenshot at 2023-08-10 10-38-17

Rolf, this seems to work great in the demo. I’m going to implement it into my code and see if it cooperates.

Thanks for coming back to me Rushin.
I have dug into this issue with the month choice, in the choice drop down being blank, as reported by both yourself and Steve2 and I remain convinced it’s a glitch in the wxWidget itself.

The code https://github.com/wxWidgets/wxWidgets/blob/3ae3a4e1f519741132c51e5aa8f83d6f05174501/src/generic/calctrlg.cpp builds a wx.Choice of the month names and I see no way that I can influence that.

void wxGenericCalendarCtrl::CreateMonthChoice()
{
    m_choiceMonth = new wxChoice(GetParent(), wxID_ANY,
                                  wxDefaultPosition,
                                  wxDefaultSize,
                                  0, nullptr);

    wxDateTime::Month m;
    for ( m = wxDateTime::Jan; m < wxDateTime::Inv_Month; wxNextMonth(m) )
    {
        m_choiceMonth->Append(wxDateTime::GetMonthName(m, wxDateTime::NameForm().Full().Standalone()));
    }

    m_choiceMonth->SetSelection(GetDate().GetMonth());
    m_choiceMonth->SetSize(wxDefaultCoord,
                          wxDefaultCoord,
                          wxDefaultCoord,
                          wxDefaultCoord,
                          wxSIZE_AUTO_WIDTH|wxSIZE_AUTO_HEIGHT);

    m_choiceMonth->Bind(wxEVT_CHOICE, &wxGenericCalendarCtrl::OnMonthChange, this);
}

In the above for ... loop my understanding is that Jan is 0 and Inv_Month is 12 (as defined in wx.DateTime), so I fail to see how that can go wrong.

So quirks aside, on Windows OS, it seems that for the moment, running with the style wx.adv.CAL_SEQUENTIAL_MONTH_SELECTION is the best option.

I’ve noticed that a commit was made to calctrlg.cpp on May 31 which changed the values used for the month names in CreateMonthChoice().

See: Use correct calendar names form in wxGenericCalendarCtrl · wxWidgets/wxWidgets@36f06bf · GitHub

I haven’t been able to tell if the later version has been incorporated in wxPython yet, or whether wxPython is still using the previous version.

EDIT: wxPython 4.2.1 uses wxWidgets 3.2.2.1 which (according to GitHub) was released Feb 13.

Therefore, wxPython must be using the version from before the commit was made.

1 Like

A request to @steve2 and @Rushin
For the purposes of trying to tie down the bug, which I can’t replicate, it would be interesting to know if using minidatepickerbutton.py or minidatepicker.py without wx.adv.CAL_SEQUENTIAL_MONTH_SELECTION, whether you can change the month with the keyboard i.e. the up/down arrow keys and the PageUp/PageDown keys.

The reason:
It would test if the month is populated properly and tie the error down to the EVT_CHOICE not being fired on the m_choiceMonth widget, however unlikely that seems.

The changes made to calctrlg.cpp appear to be related displaying month names in different languages. This made me wonder if the issue on Windows is related to locale.

@steve2 has said that the example in the wxPython demo does work correctly. I remembered that the demo explicitly sets a locale in its Main.py module:

    def InitLocale(self):
        super().InitLocale()
        self._locale = wx.Locale(wx.LANGUAGE_ENGLISH)

I wonder if doing something similar with minidatepickerbutton.py might help?

I can’t test it myself as I don’t have any Windows PCs.

As an aside @RichardT, I particularly liked your highlighting code in the code sample you left in https://github.com/wxWidgets/Phoenix/issues/2073

In the current unpublished version of minidatepicker and minidatepickerbutton, I’ve used that dictionary method, as inspiration to provide functions to mark holidays, mark specific dates which aren’t holidays, create notes that can be displayed with a Right Click and Restrict dates, making only defined dates and or days selectable.

I do hope you don’t mind but inspiration is inspiration! :smile:

Hi Rolf,

I tried:

    self.calendar = wx.adv.GenericCalendarCtrl(self, -1, wx.DateTime().Today(),
                              style = wx.adv.CAL_SHOW_HOLIDAYS
                                    | wx.adv.CAL_SUNDAY_FIRST)

But it has the same problem, months drop down list doesn’t show up.

Thanks for coming back to me @steve2.
I’m assuming that’s in some standalone code of your own. If so, then it is in fact a bug, that’s worked its way into the MS Windows version of the code.
I guess the answer for now, on Windows, is to use the wx.adv.CAL_SEQUENTIAL_MONTH_SELECTION
Out of interest, did you check @RichardT 's suggestion, about setting a locale?

I’ve got a new version, I’m just about fed up to the backteeth with, testing wise, usually a sign to release it :slight_smile: so if the dropdown month selection is something I can do nothing about, I’d like to get it out and stop torturing myself with it. :wink:

Regards,
Rolf

Hi Rolf,

Regarding @RichardT 's suggestion, I don’t exactly know how to set locale explicitly. However, in the demo I commented out the following lines:

    def InitLocale(self):
        super().InitLocale()
        self._locale = wx.Locale(wx.LANGUAGE_ENGLISH)

and the months drop down list showed up anyway. So I don’t think it might be related to it.

I also tried adding the following line in my code (I don’t know if it’s the correct way of setting a locale), but it didn’t fix the problem either:

if __name__ == '__main__':
    app = wx.App()
    wx.Locale(wx.LANGUAGE_ENGLISH)
    frame = DemoFrame(None)
    frame.Show()
    app.MainLoop()

Hi,

I think the problem is related to wx.PopupTransientWindow. It doesn’t let the drop down menu show up. Instead of wx.PopupTransientWindow, if you use wx.Frame, the drop down menu works fine.

Best Regards

1 Like

Great news, because there’s supposedly a solution.
Documented here: wxPopup(Transient)Window and combo box - wxWidgets Discussion Forum

And mentioned in the documentation:

wx.PU_CONTAINS_CONTROLS : By default in wxMSW, a popup window will not take focus from its parent window. However many standard controls, including common ones such as wx.TextCtrl, need focus to function correctly and will not work when placed on a default popup. This flag can be used to make the popup take focus and let all controls work but at the price of not allowing the parent window to keep focus while the popup is shown, which can also be sometimes desirable. This style is currently only implemented in MSW and simply does nothing under the other platforms (it’s new since wxWidgets 3.1.3).

Find the def OnCalendar(self, _event=None): definition and replace it with this:

    def OnCalendar(self, _event=None):
        if self._pop:
            return
        self._pop = True # controls only one popup at any one time
        self.calendar = CalendarPopup(
            self, self._date, self.OnDate, self.GetTopLevelParent(), wx.PU_CONTAINS_CONTROLS|wx.SIMPLE_BORDER)
        pos = self.ClientToScreen((0, 0))
        size = self.GetSize()
        self.calendar.Position(pos, (0, size.height))

Then remove the wx.adv.CAL_SEQUENTIAL_MONTH_SELECTION from the styles of self.mdp

That should do it!
If it does I’ll include in the next version.
As you’ll see, it’s an wxMSW only issue, so thanks for tracking that down for me.

Regards,
Rolf

2 Likes

Hi Rolf,

The problem is fixed when wx.PU_CONTAINS_CONTROLS style is used.

Thanks
Best Regards

Version 1.5 of minidatepicker and minidatepickerbutton

Changelog:

1.5     Add optional holidays package
        A fast, efficient Python library for generating country and subdivision- (e.g. state or province) specific
         sets of government-designated holidays on the fly.
        Alter the font_family, weight, size etc of the calendar popup
        New functions:
            AddOfficialHolidays - to add Official holiday zones using 'python holidays package'
            SetCalendarFont()   - Change calendar font_family, weight, style, size etc
        Fix for MSW, added style wx.PU_CONTAINS_CONTROLS to the Popup, which allows the month choice drop down
         to function

1.4     New Functions
         SetCalendarHolidayColours
         SetCalendarHolidays
         SetCalendarMarkBorder
         SetCalendarMarkDates
        Permit the definition of Holidays and key dates to be highlighted and the method of highlighting;
         by colour for holidays and border type, plus border colour, for marked days
        SetCalendarDateRange
         allows the restriction of dates to a range, that can be selected
        SetCalendarNotes
            Allows for notes to be assigned to individual days in the calendar.
            If notes exist for a day, when hovered over the ToolTip will display the note.
            Envisaged to be used in conjunction with Holidays and Marked days to provide detail
        SetCalendarRestrictDates
            Set a dictionary of dates that are Not selectable
        SetCalendarOnlyWeekDays
            Only weekdays are selectable i.e. weekends and holidays are not

    Navigation:
     The Escape key will exit the Calendar
     The Arrow keys will navigate the calendar
     The PageUp/PageDown keys will retreat and advance and the month respectively, as will MouseScrollUp and MouseScrollDown
     The Home and End keys jump to the First and Last day of the month, respectively.
     A right click on the calendar on a blank day, will display All the notes for the month.
     Date ToolTips will be displayed as and when appropriate, depending of the position in the calendar and settings

minidatepicker.zip (137.9 KB)

Submit bugs, comments and insults on a postcard please :wink:

1 Like

I’ll take a look at it. I recall telling everyone that the python/wxPython datetime thing was screwed up at one time and to just copy all the wx modules functions into a blank skeleton and try to rewrite them in pure python. Looks like you started on that, tho my hopes are not up as for like the last eternity there is always been some small sort of bug with the two working together and it completely screws up my DeltaTime class, which by the way is NOT a format lol.

+=.00000001 dt KABOOOM

good luck