Tkinter Grid Overlapping
I am building a calendar that allows the user to cycle through the months and years by pressing the buttons created of the previous month and next month. Essentially what I want th
Solution 1:
This is a modified version of the proposed answer that also includes the original desired intent of allowing the user to cycle through the months and will also increment the year.
from calendar import *
import datetime
try:
from tkinter import * # Python 3.xexcept:
from Tkinter import * # Python 2.xclassApplication(Frame):
def__init__(self, master=None):
Frame.__init__(self, master)
self.grid(row=0, column=0, sticky='news')
DateNow = datetime.datetime.now()
self.month = int(DateNow.month)
self.year = int(DateNow.year)
self.createDaysOfWeekLabels()
# Create frames and button controls for previous, current and next month.
self.frameList = [] # List that contains the frame objects.
self.buttonList = [] # List that contains the button objects.
self.split()
defsplit(self):
month_name = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
leftArrow = Button(self, text="<", command=self.prevMonth)
leftArrow.grid(row = 0, column = 0)
rightArrow = Button(self, text=">", command=self.nextMonth)
rightArrow.grid(row = 0, column = 1)
for i inrange(3):
try:
print i, "this is i"print self.month
mFrame = Frame(self)
self.createMonth(mFrame)
self.frameList.append(mFrame)
mButton = Button(self, text=month_name[self.month-1])
mButton['command'] = lambda f=mFrame, b=mButton: self.showMonth(f, b)
mButton.grid(row=1, column=i)
# Grid each frame
mFrame.grid(row=3, column=0, columnspan=7, sticky='news')
if (i == 1):
mButton['relief'] = 'flat'else:
mButton.grid_remove()
# Remove all but the ith frame. More efficient to remove than forget and configuration is remembered.
mFrame.grid_remove()
self.buttonList.append(mButton)
except:
pass# Create year widget at top right of top frame
label = Label(self, text=self.year)#displaying year
label.grid(row=0, column=6)
print"-------------------"defprevMonth(self):
self.month -= 1print self.month, "this is month in PREV"if self.month <= 0:
self.month = 12print self.month, "month inside forinif in PREVMONTH"
self.year -= 1elif self.month >= 13:
self.month = 0print self.month, "month inside forinelif in PREVMONTH"
self.year += 1
self.split()
defnextMonth(self):
self.month += 1print self.month, "this is month in NEXT"for frame in self.frameList:
frame.grid_remove()
if self.month <= -1:
self.month = 11print self.month, "month inside forinif in NEXTMONTH"
self.year -= 1elif self.month >= 13:
self.month = 1print self.month, "month inside forinelif in NEXTMONTH"
self.year += 1
self.split()
defcreateDaysOfWeekLabels(self):
days = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
for i inrange(7):
label = Label(self, text=days[i], width = 3)
label.grid(row = 2, column = i)
defshowMonth(self, mFrame, mButton):
# Display all buttons normallyfor button in self.buttonList:
button['relief'] = 'raised'# Set this month's button relief to flat
mButton['relief'] = 'flat'# Hide all framesfor mframe in self.frameList:
mframe.grid_remove()
mFrame.grid()
defcreateMonth(self, mFrame):
weekday, numDays = monthrange(self.year, self.month)
week = 0for i inrange(1, numDays + 1):
button = Button(mFrame, text = str(i), width=3)
button.grid(row = week, column = weekday)
weekday += 1if weekday > 6:
week += 1
weekday = 0
mainWindow = Tk()
obj = Application(mainWindow)
mainWindow.mainloop()
Solution 2:
Tkinter is fairly efficient. And for the number of widgets that you have, it won't impact performance much to create them all initially. Here is a sample that works about like what you were trying to do.
from calendar import *
import datetime
try:
from tkinter import * # Python 3.xexcept:
from Tkinter import * # Python 2.xclassApplication(Frame):
def__init__(self, master=None):
Frame.__init__(self, master)
self.grid(row=0, column=0, sticky='news')
DateNow = datetime.datetime.now()
month = int(DateNow.month)
year = int(DateNow.year)
self.createDaysOfWeekLabels()
month_name = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
# Create frames and button controls for previous, current and next month.
self.frameList = [] # List that contains the frame objects.
self.buttonList = [] # List that contains the button objects.
amonth = month - 1for i inrange(3):
if amonth < 0:
amonth = 11
year -= 1elif amonth == 12:
amonth = 0
year += 1
mFrame = Frame(self)
self.createMonth(mFrame, amonth, year)
self.frameList.append(mFrame)
mButton = Button(self, text=month_name[amonth-1])
mButton['command'] = lambda f=mFrame, b=mButton: self.showMonth(f, b)
mButton.grid(row=0, column=i)
# Grid each frame
mFrame.grid(row=2, column=0, columnspan=7, sticky='news')
if (i == 1):
mButton['relief'] = 'flat'else:
# Remove all but the ith frame. More efficient to remove than forget and configuration is remembered.
mFrame.grid_remove()
self.buttonList.append(mButton)
amonth += 1# Create year widget at top left of top frame
label = Label(self, text=year)#displaying year
label.grid(row=0, column=6)
defcreateDaysOfWeekLabels(self):
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
for i inrange(7):
label = Label(self, text=days[i])
label.grid(row = 1, column = i)
defshowMonth(self, mFrame, mButton):
# Display all buttons normallyfor button in self.buttonList:
button['relief'] = 'raised'# Set this month's button relief to flat
mButton['relief'] = 'flat'# Hide all framesfor frame in self.frameList:
frame.grid_remove()
mFrame.grid()
defcreateMonth(self, mFrame, month, year):
weekday, numDays = monthrange(year, month)
week = 0for i inrange(1, numDays + 1):
button = Button(mFrame, text = str(i), width=3)
button.grid(row = week, column = weekday)
weekday += 1if weekday > 6:
week += 1
weekday = 0
mainWindow = Tk()
obj = Application(mainWindow)
mainWindow.mainloop()
Post a Comment for "Tkinter Grid Overlapping"