How do I create a date picker in tkinter?

前端 未结 7 1342
借酒劲吻你
借酒劲吻你 2020-11-28 09:45

Is there any standard way tkinter apps allow the user to choose a date?

相关标签:
7条回答
  • 2020-11-28 10:11

    For updated python guys should use this: pip3 install tkcalendar it will start installing in their CMD. After successful it.

    Use this: from tkcalendar import Calendar

    0 讨论(0)
  • 2020-11-28 10:13

    This is how we code a python datepicker in tkinter.

    # !/usr/bin/env python
    # -*- coding: utf-8 -*-
    # Author: Rambarun Komaljeet
    # License: Freeware
    # ---------------------------------------------------------------------------
    import calendar
    import tkinter as tk
    import time
    from tkinter import ttk
    
    
    class MyDatePicker(tk.Toplevel):
        """
        Description:
            A tkinter GUI date picker.
        """
    
        def __init__(self, widget=None, format_str=None):
            """
            :param widget: widget of parent instance.
    
            :param format_str: print format in which to display date.
            :type format_str: string
    
            Example::
                a = MyDatePicker(self, widget=self.parent widget,
                                 format_str='%02d-%s-%s')
            """
    
            super().__init__()
            self.widget = widget
            self.str_format = format_str
    
            self.title("Date Picker")
            self.resizable(0, 0)
            self.geometry("+630+390")
    
            self.init_frames()
            self.init_needed_vars()
            self.init_month_year_labels()
            self.init_buttons()
            self.space_between_widgets()
            self.fill_days()
            self.make_calendar()
    
        def init_frames(self):
            self.frame1 = tk.Frame(self)
            self.frame1.pack()
    
            self.frame_days = tk.Frame(self)
            self.frame_days.pack()
    
        def init_needed_vars(self):
            self.month_names = tuple(calendar.month_name)
            self.day_names = tuple(calendar.day_abbr)
            self.year = time.strftime("%Y")
            self.month = time.strftime("%B")
    
        def init_month_year_labels(self):
            self.year_str_var = tk.StringVar()
            self.month_str_var = tk.StringVar()
    
            self.year_str_var.set(self.year)
            self.year_lbl = tk.Label(self.frame1, textvariable=self.year_str_var,
                                     width=3)
            self.year_lbl.grid(row=0, column=5)
    
            self.month_str_var.set(self.month)
            self.month_lbl = tk.Label(self.frame1, textvariable=self.month_str_var,
                                      width=8)
            self.month_lbl.grid(row=0, column=1)
    
        def init_buttons(self):
            self.left_yr = ttk.Button(self.frame1, text="←", width=5,
                                      command=self.prev_year)
            self.left_yr.grid(row=0, column=4)
    
            self.right_yr = ttk.Button(self.frame1, text="→", width=5,
                                       command=self.next_year)
            self.right_yr.grid(row=0, column=6)
    
            self.left_mon = ttk.Button(self.frame1, text="←", width=5,
                                       command=self.prev_month)
            self.left_mon.grid(row=0, column=0)
    
            self.right_mon = ttk.Button(self.frame1, text="→", width=5,
                                        command=self.next_month)
            self.right_mon.grid(row=0, column=2)
    
        def space_between_widgets(self):
            self.frame1.grid_columnconfigure(3, minsize=40)
    
        def prev_year(self):
            self.prev_yr = int(self.year_str_var.get()) - 1
            self.year_str_var.set(self.prev_yr)
    
            self.make_calendar()
    
        def next_year(self):
            self.next_yr = int(self.year_str_var.get()) + 1
            self.year_str_var.set(self.next_yr)
    
            self.make_calendar()
    
        def prev_month(self):
            index_current_month = self.month_names.index(self.month_str_var.get())
            index_prev_month = index_current_month - 1
    
            #  index 0 is empty string, use index 12 instead,
            # which is index of December.
            if index_prev_month == 0:
                self.month_str_var.set(self.month_names[12])
            else:
                self.month_str_var.set(self.month_names[index_current_month - 1])
    
            self.make_calendar()
    
        def next_month(self):
            index_current_month = self.month_names.index(self.month_str_var.get())
    
            try:
                self.month_str_var.set(self.month_names[index_current_month + 1])
            except IndexError:
                #  index 13 does not exist, use index 1 instead, which is January.
                self.month_str_var.set(self.month_names[1])
    
            self.make_calendar()
    
        def fill_days(self):
            col = 0
            #  Creates days label
            for day in self.day_names:
                self.lbl_day = tk.Label(self.frame_days, text=day)
                self.lbl_day.grid(row=0, column=col)
                col += 1
    
        def make_calendar(self):
            #  Delete date buttons if already present.
            #  Each button must have its own instance attribute for this to work.
            try:
                for dates in self.m_cal:
                    for date in dates:
                        if date == 0:
                            continue
    
                        self.delete_buttons(date)
    
            except AttributeError:
                pass
    
            year = int(self.year_str_var.get())
            month = self.month_names.index(self.month_str_var.get())
            self.m_cal = calendar.monthcalendar(year, month)
    
            #  build dates buttons.
            for dates in self.m_cal:
                row = self.m_cal.index(dates) + 1
                for date in dates:
                    col = dates.index(date)
    
                    if date == 0:
                        continue
    
                    self.make_button(str(date), str(row), str(col))
    
        def make_button(self, date, row, column):
            """
            Description:
                Build a date button.
    
            :param date: date.
            :type date: string
    
            :param row: row number.
            :type row: string
    
            :param column: column number.
            :type column: string
            """
            exec(
                "self.btn_" + date + " = ttk.Button(self.frame_days, text=" + date
                + ", width=5)\n"
                "self.btn_" + date + ".grid(row=" + row + " , column=" + column
                + ")\n"
                "self.btn_" + date + ".bind(\"<Button-1>\", self.get_date)"
            )
    
        def delete_buttons(self, date):
            """
            Description:
                Delete a date button.
    
            :param date: date.
            :type: string
            """
            exec(
                "self.btn_" + str(date) + ".destroy()"
            )
    
        def get_date(self, clicked=None):
            """
            Description:
                Get the date from the calendar on button click.
    
            :param clicked: button clicked event.
            :type clicked: tkinter event
            """
    
            clicked_button = clicked.widget
            year = self.year_str_var.get()
            month = self.month_str_var.get()
            date = clicked_button['text']
    
            self.full_date = self.str_format % (date, month, year)
            print(self.full_date)
            #  Replace with parent 'widget' of your choice.
            try:
                self.widget.delete(0, tk.END)
                self.widget.insert(0, self.full_date)
            except AttributeError:
                pass
    
    
    if __name__ == '__main__':
        def application():
            MyDatePicker(format_str='%02d-%s-%s')
    
        root = tk.Tk()
        btn = tk.Button(root, text="test", command=application)
        btn.pack()
        root.mainloop()
    
    0 讨论(0)
  • 2020-11-28 10:19

    Try with the following:

    from tkinter import *
    
    from tkcalendar import Calendar,DateEntry
    
    root = Tk()
    
    cal = DateEntry(root,width=30,bg="darkblue",fg="white",year=2010)
    
    cal.grid()
    
    root.mainloop()
    

    where tkcalendar library should be downloaded and installed through pip install tkcalender command.

    0 讨论(0)
  • 2020-11-28 10:21

    No, but you can get it from the user as a datetime element from a formatted string..

    Example:

    import datetime
    
    userdatestring = '2013-05-10'
    thedate = datetime.datetime.strptime(userdatestring, '%Y-%m-%d') 
    

    Check out http://docs.python.org/2/library/datetime.html#strftime-strptime-behavior. It's handy, although not the most user friendly way of getting a date.

    0 讨论(0)
  • 2020-11-28 10:23

    The answers here provide most of what you asked for, but I felt none of them were completely satisfying. As a Tkinter newbie, I needed more hand-holding. My complaints:

    1. Assuming I want the calendar to default to a 2012 date rather than today's date,
    2. Not returning the result as a variable for future use,
    3. An unnecessary top layer menu before getting to the calendar, and
    4. Not cleaning up the windows and exiting mainloop after a selection has been made.

    So with gratitude to the previous answers which helped me immensely, here's my version.

    def get_date():
        import tkinter as tk
        from tkinter import ttk
        from tkcalendar import Calendar, DateEntry
    
        def cal_done():
            top.withdraw()
            root.quit()
    
        root = tk.Tk()
        root.withdraw() # keep the root window from appearing
    
        top = tk.Toplevel(root)
    
        cal = Calendar(top,
                       font="Arial 14", selectmode='day',
                       cursor="hand1")
        cal.pack(fill="both", expand=True)
        ttk.Button(top, text="ok", command=cal_done).pack()
    
        selected_date = None
        root.mainloop()
        return cal.selection_get()
    
    selection = get_date()
    print(selection)
    
    0 讨论(0)
  • 2020-11-28 10:26

    In case anyone still needs this - here's a simple code to create a Calendar and DateEntry widget using tkcalendar package.

    pip install tkcalendar (for installing the package)

    try:
        import tkinter as tk
        from tkinter import ttk
    except ImportError:
        import Tkinter as tk
        import ttk
    
    from tkcalendar import Calendar, DateEntry
    
    def example1():
        def print_sel():
            print(cal.selection_get())
    
        top = tk.Toplevel(root)
    
        cal = Calendar(top,
                       font="Arial 14", selectmode='day',
                       cursor="hand1", year=2018, month=2, day=5)
        cal.pack(fill="both", expand=True)
        ttk.Button(top, text="ok", command=print_sel).pack()
    
    def example2():
        top = tk.Toplevel(root)
    
        ttk.Label(top, text='Choose date').pack(padx=10, pady=10)
    
        cal = DateEntry(top, width=12, background='darkblue',
                        foreground='white', borderwidth=2)
        cal.pack(padx=10, pady=10)
    
    root = tk.Tk()
    s = ttk.Style(root)
    s.theme_use('clam')
    
    ttk.Button(root, text='Calendar', command=example1).pack(padx=10, pady=10)
    ttk.Button(root, text='DateEntry', command=example2).pack(padx=10, pady=10)
    
    root.mainloop()
    
    0 讨论(0)
提交回复
热议问题