Calendar with tkinter (print the selected date)

2024/10/11 2:18:53

I got this code online in order to create a calendar with tkinter:

"""
Simple calendar using ttk Treeview together with calendar and datetime
classes.
"""
import calendar
import tkinter
import tkinter.font
from tkinter import ttkdef get_calendar(locale, fwday):# instantiate proper calendar classif locale is None:return calendar.TextCalendar(fwday)else:return calendar.LocaleTextCalendar(fwday, locale)class Calendar(ttk.Frame):# XXX ToDo: cget and configuredatetime = calendar.datetime.datetimetimedelta = calendar.datetime.timedeltadef __init__(self, master=None, **kw):"""WIDGET-SPECIFIC OPTIONSlocale, firstweekday, year, month, selectbackground,selectforeground"""# remove custom options from kw before initializating ttk.Framefwday = kw.pop('firstweekday', calendar.MONDAY)year = kw.pop('year', self.datetime.now().year)month = kw.pop('month', self.datetime.now().month)locale = kw.pop('locale', None)sel_bg = kw.pop('selectbackground', '#ecffc4')sel_fg = kw.pop('selectforeground', '#05640e')self._date = self.datetime(year, month, 1)self._selection = None # no date selectedttk.Frame.__init__(self, master, **kw)self._cal = get_calendar(locale, fwday)self.__setup_styles()       # creates custom stylesself.__place_widgets()      # pack/grid used widgetsself.__config_calendar()    # adjust calendar columns and setup tags# configure a canvas, and proper bindings, for selecting datesself.__setup_selection(sel_bg, sel_fg)# store items ids, used for insertion laterself._items = [self._calendar.insert('', 'end', values='')for _ in range(6)]# insert dates in the currently empty calendarself._build_calendar()# set the minimal size for the widget#self._calendar.bind('<Map>', self.__minsize)def __setitem__(self, item, value):if item in ('year', 'month'):raise AttributeError("attribute '%s' is not writeable" % item)elif item == 'selectbackground':self._canvas['background'] = valueelif item == 'selectforeground':self._canvas.itemconfigure(self._canvas.text, item=value)else:ttk.Frame.__setitem__(self, item, value)def __getitem__(self, item):if item in ('year', 'month'):return getattr(self._date, item)elif item == 'selectbackground':return self._canvas['background']elif item == 'selectforeground':return self._canvas.itemcget(self._canvas.text, 'fill')else:r = ttk.tclobjs_to_py({item: ttk.Frame.__getitem__(self, item)})return r[item]def __setup_styles(self):# custom ttk stylesstyle = ttk.Style(self.master)arrow_layout = lambda dir: ([('Button.focus', {'children': [('Button.%sarrow' % dir, None)]})])style.layout('L.TButton', arrow_layout('left'))style.layout('R.TButton', arrow_layout('right'))def __place_widgets(self):# header frame and its widgetshframe = ttk.Frame(self)lbtn = ttk.Button(hframe, style='L.TButton', command=self._prev_month)rbtn = ttk.Button(hframe, style='R.TButton', command=self._next_month)self._header = ttk.Label(hframe, width=15, anchor='center')# the calendar#self._calendar = ttk.Treeview(show='', selectmode='none', height=7)self._calendar = ttk.Treeview(self, show='', selectmode='none', height=7)# pack the widgetshframe.pack(in_=self, side='top', pady=4, anchor='center')lbtn.grid(in_=hframe)self._header.grid(in_=hframe, column=1, row=0, padx=12)rbtn.grid(in_=hframe, column=2, row=0)self._calendar.pack(in_=self, expand=1, fill='both', side='bottom')def __config_calendar(self):cols = self._cal.formatweekheader(3).split()self._calendar['columns'] = colsself._calendar.tag_configure('header', background='grey90')self._calendar.insert('', 'end', values=cols, tag='header')# adjust its columns widthfont = tkinter.font.Font()maxwidth = max(font.measure(col) for col in cols)for col in cols:self._calendar.column(col, width=maxwidth, minwidth=maxwidth,anchor='e')def __setup_selection(self, sel_bg, sel_fg):self._font = tkinter.font.Font()self._canvas = canvas = tkinter.Canvas(self._calendar,background=sel_bg, borderwidth=0, highlightthickness=0)canvas.text = canvas.create_text(0, 0, fill=sel_fg, anchor='w')canvas.bind('<ButtonPress-1>', lambda evt: canvas.place_forget())self._calendar.bind('<Configure>', lambda evt: canvas.place_forget())self._calendar.bind('<ButtonPress-1>', self._pressed)#def __minsize(self, evt):#    width, height = self._calendar.master.geometry().split('x')#    height = height[:height.index('+')]#    self._calendar.master.minsize(width, height)def _build_calendar(self):year, month = self._date.year, self._date.month# update header text (Month, YEAR)header = self._cal.formatmonthname(year, month, 0)self._header['text'] = header.title()# update calendar shown datescal = self._cal.monthdayscalendar(year, month)for indx, item in enumerate(self._items):week = cal[indx] if indx < len(cal) else []fmt_week = [('%02d' % day) if day else '' for day in week]self._calendar.item(item, values=fmt_week)def _show_selection(self, text, bbox):"""Configure canvas for a new selection."""x, y, width, height = bboxtextw = self._font.measure(text)canvas = self._canvascanvas.configure(width=width, height=height)canvas.coords(canvas.text, width - textw, height / 2 - 1)canvas.itemconfigure(canvas.text, text=text)canvas.place(in_=self._calendar, x=x, y=y)# Callbacksdef _pressed(self, evt):"""Clicked somewhere in the calendar."""x, y, widget = evt.x, evt.y, evt.widgetitem = widget.identify_row(y)column = widget.identify_column(x)if not column or not item in self._items:# clicked in the weekdays row or just outside the columnsreturnitem_values = widget.item(item)['values']if not len(item_values): # row is empty for this monthreturntext = item_values[int(column[1]) - 1]if not text: # date is emptyreturnbbox = widget.bbox(item, column)if not bbox: # calendar not visible yetreturn# update and then show selectiontext = '%02d' % textself._selection = (text, item, column)self._show_selection(text, bbox)def _prev_month(self):"""Updated calendar to show the previous month."""self._canvas.place_forget()self._date = self._date - self.timedelta(days=1)self._date = self.datetime(self._date.year, self._date.month, 1)self._build_calendar() # reconstuct calendardef _next_month(self):"""Update calendar to show the next month."""self._canvas.place_forget()year, month = self._date.year, self._date.monthself._date = self._date + self.timedelta(days=calendar.monthrange(year, month)[1] + 1)self._date = self.datetime(self._date.year, self._date.month, 1)self._build_calendar() # reconstruct calendar# Properties@propertydef selection(self):"""Return a datetime representing the current selected date."""if not self._selection:return Noneyear, month = self._date.year, self._date.monthreturn self.datetime(year, month, int(self._selection[0]))def test():import sysroot = tkinter.Tk()root.title('Ttk Calendar')ttkcal = Calendar(firstweekday=calendar.SUNDAY)ttkcal.pack(expand=1, fill='both')if 'win' not in sys.platform:style = ttk.Style()style.theme_use('clam')root.mainloop()if __name__ == '__main__':test()

It works perfectly fine. The calendar opens and I can select dates and everything. I just have one very important question. Where in this code can I put something as easy as:

print(selected_date)

And format it using the datetime module? (I know how to use datetime just in case) I just can't figure out in which part to get the entire date the user selected, I have just been able to get the day. By entire date I mean yyyy-mm-dd.

Any help will be appreciated. Thanks!!

Answer

Honestly, the answer is that you can put the code wherever you want. Normally you would do this in response to an event, such as the user clicking a button, submitting a form, etc.

Here's an example that gives you a button that will print whatever date is selected. Right before the call to mainloop you can add this code:

def print_date():print "the date is:", ttkcal.selectiontkinter.Button(root, text="Print it!", command=print_date).pack()

When you click on the button, the selected date will be printed out in the terminal window where you started the program.

https://en.xdnf.cn/q/118378.html

Related Q&A

Python Tkinter scrollbar in multiple tabs

I learned how to make a scrollable frame by embedding the frame in a canvas and then adding a scrollbar to it like this:def __add_widget_features(self, feat_tab):table_frame = ttk.Frame(feat_tab)table_…

ValueError: setting an array element with a sequence error is showing

I am trying to convert this column in float type from object type but it is giving this error. import pandas as pddf = pd.DataFrame({col1: [[-0.8783137, 0.05478287, -0.08827557, 0.69203985, 0.06209986]…

Are there any datetime.tzinfo implementations in C?

Ive been working on a Python library that uses a C extension module to do ISO 8601 parsing.Part of that work requires the creation of tzinfo objects, which is by far the slowest part of the parse. Call…

How to open telnet as a textfile rather than a binary file

So I was trying to use the read_until method in telnet but then ran into the error: Traceback (most recent call last): File "c:\Users\Desktop\7DTD Bot\test.py", line 44, in <module> tn.…

The algorithm for dividing the range of subnet

There is a interesting algorithm, wrt dividing the range of subnet.I have a subnet,such as 192.168.1.0/24 or 192.168.1.248/22, and so on. And we know that /24 or /22 stands for networks and (32 - 24) o…

Look if a string starts with the ending characters of another string?

I want to see if ending of one string is similar to starting of another stringif i have a string a="12345678" and b="56789" i want to update a as 123456789these two strings are in …

Dict and List Manipulation Python

I have two files one has key and other has both key and value. I have to match the key of file one and pull the corresponding value from file two. When all the key and value are in plain column format …

Python - input of file path

this code works fine when I put the path of the file myself. but when I want to get it from users raw_input() it doesnt work. what can I do?import string import randomprint "enter number between …

libmproxy and mitmproxy documentation

I am new to the mitmproxy world. I need to write a python script that would log all the requests made from a certain app on Genymotion emulator. Now, I learned that mitmproxy can be helpful for my requ…

Printing mutiple HTML tables using tabulate in python

I want to produce two HTML tables using tabulate package, but I am only able to produce one table and send mail.Is it possible to put more than one html table into a message sent with smtplib and email…