[tkinter] calendar widget

Post here if you need help with creating a Graphical User Interface in Python.

[tkinter] calendar widget

Postby metulburr » Tue Jul 23, 2013 1:18 pm

I figured to make a simple widget, one where the dates are buttons, instead of setting up canvas with backgrounds that change color when mouse is over them, and what not.

I am trying to make a tkinter calendar widget. AKA a date picker. I got the structure already down, I am making it to fit in a Toplevel child window, and return the date back to be used in the root window. Currenlty i do not have a child window, but i can figure out how ot grab the date in root anyhow. Currenlty self.selected is either default or 0 when a button is pressed. Maybe i am forgettign something simple?

I was expecting:
Code: Select all
b = tk.Button(self.parent, width=1, text=day, command=lambda:self.selection(day))

this to send day to the function, and display its contents upon press, but it returns 0 every time, sometimes it return 31 randomly though, but mostly 0?

my expected outcome is when you press the button of a given day, self.selected has some retention to what day button was pressed, as to either return it or display it in a label below.

Code: Select all

import calendar
import tkinter as tk
import datetime

class Calendar:
    def __init__(self, parent):
        self.parent = parent
        self.cal = calendar.TextCalendar(calendar.SUNDAY)
        self.year = 2013
        self.month = 7
        self.wid = []
        self.selected = 'test'
       
        self.setup(self.year, self.month)
       
    def clear(self):
        for w in self.wid[:]:
            w.grid_forget()
            #w.destroy()
            self.wid.remove(w)
   
    def go_prev(self):
        if self.month > 1:
            self.month -= 1
        else:
            self.month = 12
            self.year -= 1
        #self.selected = (self.month, self.year)
        self.clear()
        self.setup(self.year, self.month)

    def go_next(self):
        if self.month < 12:
            self.month += 1
        else:
            self.month = 1
            self.year += 1
        #self.selected = (self.month, self.year)
        self.clear()
        self.setup(self.year, self.month)
       
    def selection(self, day):
        self.selected = day
        print(day)
       
    def setup(self, y, m):
        left = tk.Button(self.parent, text='<', command=self.go_prev)
        self.wid.append(left)
        left.grid(row=0, column=1)
       
        header = tk.Label(self.parent, height=2, text='{}   {}'.format(calendar.month_abbr[m], str(y)))
        self.wid.append(header)
        header.grid(row=0, column=2, columnspan=3)
       
        right = tk.Button(self.parent, text='>', command=self.go_next)
        self.wid.append(right)
        right.grid(row=0, column=5)
       
        days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
        for num, name in enumerate(days):
            t = tk.Label(self.parent, text=name)
            self.wid.append(t)
            t.grid(row=1, column=num)
       
        for w, week in enumerate(self.cal.monthdayscalendar(y, m), 2):
            for d, day in enumerate(week):
                if day != 0:
                    b = tk.Button(self.parent, width=1, text=day, command=lambda:self.selection(day))
                    self.wid.append(b)
                    b.grid(row=w, column=d)
                   
        sel = tk.Label(self.parent, height=2, text=self.selected)
        self.wid.append(sel)
        sel.grid(row=8, column=2, columnspan=3)
       
        ok = tk.Button(self.parent, width=5, text='OK', command='disabled')
        self.wid.append(ok)
        ok.grid(row=9, column=2, columnspan=3, pady=10)

root = tk.Tk()
cal = Calendar(root)
root.mainloop()




EDIT:
ok so i get the smae results on small scale. What is exactly going on here?
Code: Select all
import tkinter as tk

root = tk.Tk()

def disp(arg):
    print(arg)

for i in range(10):
    tk.Button(root, text=i, command=lambda:disp(i)).pack()

root.mainloop()
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1387
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: [tkinter] calendar widget

Postby metulburr » Tue Jul 23, 2013 1:49 pm

ok figured it out,
Code: Select all
lambda i=i:self.selection(i)


python3.x
Code: Select all

import calendar
import tkinter as tk
import datetime

class Data:
    def __init__(self):
        self.day_selected = 0
        self.month_selected = 0
        self.year_selected = 0
        self.day_name = 0

class Calendar:
    def __init__(self, parent, data):
        self.data = data
        self.parent = parent
        self.cal = calendar.TextCalendar(calendar.SUNDAY)
        self.year = 2013
        self.month = 7
        self.wid = []
        self.day_selected = 1
        self.month_selected = self.month
        self.year_selected = self.year
        self.day_name = ''
       
        self.setup(self.year, self.month)
       
    def clear(self):
        for w in self.wid[:]:
            w.grid_forget()
            #w.destroy()
            self.wid.remove(w)
   
    def go_prev(self):
        if self.month > 1:
            self.month -= 1
        else:
            self.month = 12
            self.year -= 1
        #self.selected = (self.month, self.year)
        self.clear()
        self.setup(self.year, self.month)

    def go_next(self):
        if self.month < 12:
            self.month += 1
        else:
            self.month = 1
            self.year += 1
       
        #self.selected = (self.month, self.year)
        self.clear()
        self.setup(self.year, self.month)
       
    def selection(self, day, name):
        self.day_selected = day
        self.month_selected = self.month
        self.year_selected = self.year
        self.day_name = name
       
        self.data.day_selected = day
        self.data.month_selected = self.month
        self.data.year_selected = self.year
        self.data.day_name = name
       
        #self.selected = day
        self.clear()
        self.setup(self.year, self.month)
       
    def setup(self, y, m):
        left = tk.Button(self.parent, text='<', command=self.go_prev)
        self.wid.append(left)
        left.grid(row=0, column=1)
       
        header = tk.Label(self.parent, height=2, text='{}   {}'.format(calendar.month_abbr[m], str(y)))
        self.wid.append(header)
        header.grid(row=0, column=2, columnspan=3)
       
        right = tk.Button(self.parent, text='>', command=self.go_next)
        self.wid.append(right)
        right.grid(row=0, column=5)
       
        days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
        for num, name in enumerate(days):
            t = tk.Label(self.parent, text=name[:3])
            self.wid.append(t)
            t.grid(row=1, column=num)
       
        for w, week in enumerate(self.cal.monthdayscalendar(y, m), 2):
            for d, day in enumerate(week):
                if day:
                    #print(calendar.day_name[day])
                    b = tk.Button(self.parent, width=1, text=day, command=lambda day=day:self.selection(day, calendar.day_name[(day-1) % 7]))
                    self.wid.append(b)
                    b.grid(row=w, column=d)
                   
        sel = tk.Label(self.parent, height=2, text='{} {} {} {}'.format(
            self.day_name, calendar.month_name[self.month_selected], self.day_selected, self.year_selected))
        self.wid.append(sel)
        sel.grid(row=8, column=0, columnspan=7)
       
        ok = tk.Button(self.parent, width=5, text='OK', command='disabled')
        self.wid.append(ok)
        ok.grid(row=9, column=2, columnspan=3, pady=10)
       
def win(parent, d):
    win = tk.Toplevel(parent)
    cal = Calendar(win, d)

data = Data()
root = tk.Tk()
tk.Button(root, text='calendar', command=lambda:win(root, data)).grid()

root.mainloop()

print(data.__dict__)


New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1387
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY


Return to GUI

Who is online

Users browsing this forum: No registered users and 2 guests