Alvaro Morales Solis
Alvaro Morales Solis

Reputation: 239

TTKCalendar selection return Python

I have this ttk calendar and my program is meant to update a field when a date in the calendar widget is pressed.

Here are the start_date and end_date fields:

start_date = StringVar()
start_date = ttk.Entry(f2, width=15, textvariable=start_date)
start_date.grid(column=2, row=1, sticky=E)

ttk.Label(f2, text="Start date:", width=10).grid(column=1, row=1, sticky=E)

end_date = StringVar()
end_date = ttk.Entry(f2, width=15, textvariable=end_date)
end_date.grid(column=2, row=2, sticky=E)

ttk.Label(f2, text="End date:", width=10).grid(column=1, row=2, sticky=E)

Here's the function that the button triggers:

def callbackCal():
    root2=Toplevel(f2)
    ttkcal = ttkcalendar.Calendar(root2,firstweekday=calendar.SUNDAY)
    ttkcal.pack(expand=1, fill='both')
    root2.update()
    root2.minsize(root2.winfo_reqwidth(), root2.winfo_reqheight())

Here's the button code:

b=ttk.Button(f2, width=4, text="Cal", command=callbackCal).grid(column=3,row=1, sticky=W)

Thanks to NorthCat's help, I was able to get this far. And I know the ttk calendar has the methods _pressed() , _show_selection() and selection(). But I have no idea how I can use them in order to show the selected date when it is clicked. And also, to close the calendar widget once that is done.

Thanks a lot! and sorry for these newbie questions.

Upvotes: 1

Views: 1750

Answers (1)

jimscafe
jimscafe

Reputation: 1091

I don't pretend to understand the code, but I found an answer to another question that suggested a few changes, the answer was from kalgasnik

Python tkinter with ttk calendar

Then I made this change :-

    def __init__(self, master=None, selection_callback=None, **kw):

and added this in the init function

        self.selection_callback = selection_callback

In the _pressed function I added

        if self.selection_callback:
            self.selection_callback(self.selection)

Basically adding a callback to get the values when a date is clicked.

My sample callback program was :-

import calendar
import tkinter as TK
import tkinter.font
from tkinter import ttk
from ttk_calendar import Calendar
import sys


class Test():
    def __init__(self, root):
        self.root = root
        self.root.title('Ttk Calendar')
        frame = ttk.Frame(self.root)
        frame.pack()
        quit_button = ttk.Button(frame, text="Calendar", command=self.use_calendar)
        quit_button.pack()
        self.calendarroot = None
    def use_calendar(self):
        if not self.calendarroot:
            self.calendarroot=TK.Toplevel(self.root)
            ttkcal = Calendar(master=self.calendarroot, selection_callback=self.get_selection, firstweekday=calendar.SUNDAY)
            ttkcal.pack(expand=1, fill='both')
            self.calendarroot.update()
            self.calendarroot.minsize(self.calendarroot.winfo_reqwidth(), self.calendarroot.winfo_reqheight())
        else:
            self.calendarroot.deiconify() # Restore hidden calendar

    def get_selection(self, selection):
        print (selection)
        self.calendarroot.withdraw() # Hide calendar - if that is what is required

if __name__ == '__main__':
    root = tkinter.Tk()
    x = Test(root)
    root.mainloop()

I tried to destroy the TopLevel frame but got an error, hence I used withdraw and deiconify, not best, but at least I got something to work.

A bit of a muddled answer I realize, but you might be agle to figure out a better solution.

Upvotes: 1

Related Questions