tkinter网格重叠

时间:2018-03-21 00:19:44

标签: python tkinter

我正在构建一个日历,允许用户按下上个月和下个月创建的按钮来循环显示月份和年份。基本上我想要主窗口做的是在点击PREV或NEXT月份时使用正确的日期更新新月,它只会发出日期按钮,显示月份的特定日期重叠。 以下是我遇到问题的部分:

def prevMonth(self):
        try:
            self.grid_forget()
            #SHOULD REFRESH THE WINDOW SO BUTTONS DONT OVERLAP
            print "forgeting" 

        except:
            print "passed the forgetting"
            pass
        lastMonth = self.month - 1 
        self.month = lastMonth
        self.curr_month()

    def nextMonth(self):
        try:
            self.grid_forget()
            #SHOULD REFRESH THE WINDOW SO BUTTONS DONT OVERLAP
            print "forgeting"

        except:
            print "passed the forgetting"
            pass
        nextMonth = self.month + 1
        self.month = nextMonth
        self.curr_month()

当程序在网格不刷新的月份之间迭代时,它只会重叠日期和月份。我已经尝试过在研究时间里找到的一切。 “self.destroy()”只是创建一个空白窗口。 “self.grid.destroy()”返回错误,该函数没有属性破坏。我已经尝试让网格的孩子在自己内部的所有全局变量,我不能正确地遍历几个月,所以设置是永久性的,但我觉得我错过了一些简单的工作,刷新网格并重新打印基于更新月份。

您能否指出我正确的方向或纠正我错过的错误?

以下是整个计划

from Tkinter import *
from calendar import *
import datetime

class Application(Frame):

def __init__(self, master=None):
    Frame.__init__(self, master)
    self.grid()
    DateNow = datetime.datetime.now()
    self.year = DateNow.year#declaring global variable year
    self.month = DateNow.month#declaring global variable month
    self.curr_month()



def curr_month(self):
    try:#iterating the month and year backward if index is out of range
        if self.month == 0:
            self.month = 12
            trueYear = int(self.year)
            self.year = trueYear - 1
    except:
        pass
    try:#iterating month and year forward if index is out of range
        if self.month == 13:
            self.month = 1
            trueYear = int(self.year)
            self.year = trueYear + 1
    except:
        pass


    days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
#create labels


    self.label = Label(self, text=months[self.month - 1])#displaying month
    self.label.grid(row=0, column = 1)
    self.label = Label(self, text=self.year)#displaying year
    self.label.grid(row=0, column = 6)


    try:#displaying previous month
        prevMonthBut = Button(self, text=months[self.month-2], command=self.prevMonth)
        prevMonthBut.grid(row=0,column=0)
    except:#USED ONLY IF PREVIOUS MONTH IS IN PREVIOUS YEAR
        prevMonthBut = Button(self, text=months[11], command=self.prevMonth)
        prevMonthBut.grid(row=0,column=0)
    try:#displaying next month 
        nextMonthBut = Button(self, text=months[self.month], command=self.nextMonth)
        nextMonthBut.grid(row=0,column=2)
    except:#USED ONLY IF NEXT MONTH IS IN NEXT YEAR
        nextMonthBut = Button(self, text=months[0], command=self.nextMonth)
        nextMonthBut.grid(row=0,column=2)
    for i in range(7):
        self.label = Label(self, text=days[i])
        self.label.grid(row = 1, column = i)

    weekday, numDays = monthrange(self.year, self.month)
    week = 2
    for i in range(1, numDays + 1):
        self.button = Button(self, text = str(i))
        self.button.grid(row = week, column = weekday)

        weekday += 1

        if weekday > 6:
            week += 1
            weekday = 0


def prevMonth(self):
    try:
        self.grid_forget()
        #SHOULD REFRESH THE WINDOW SO BUTTONS DONT OVERLAP
        print "forgeting" 

    except:
        print "passed the forgetting"
        pass
    lastMonth = self.month - 1 
    self.month = lastMonth
    self.curr_month()

def nextMonth(self):
    try:
        self.grid_forget()
        #SHOULD REFRESH THE WINDOW SO BUTTONS DONT OVERLAP
        print "forgeting"

    except:
        print "passed the forgetting"
        pass
    nextMonth = self.month + 1
    self.month = nextMonth
    self.curr_month()

mainWindow = Tk()
obj = Application()
mainWindow.mainloop()here

2 个答案:

答案 0 :(得分:1)

这是建议答案的修改版本,其中还包括允许用户在月份中循环并且还将增加年份的原始期望意图。

from calendar import *
import datetime
try:
    from tkinter import *   # Python 3.x
except:
    from Tkinter import *   # Python 2.x


class Application(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()

    def split(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 in range(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 "-------------------"

    def prevMonth(self):

        self.month -= 1
        print self.month, "this is month in PREV"
        if self.month <= 0:
            self.month = 12
            print self.month, "month inside forinif in PREVMONTH"
            self.year -= 1
        elif self.month >= 13:
            self.month = 0
            print self.month, "month inside forinelif in PREVMONTH"
            self.year += 1
        self.split()

    def nextMonth(self):

        self.month += 1
        print self.month, "this is month in NEXT"
        for frame in self.frameList:
            frame.grid_remove()

        if self.month <= -1:
            self.month = 11
            print self.month, "month inside forinif in NEXTMONTH"
            self.year -= 1
        elif self.month >= 13:
            self.month = 1
            print self.month, "month inside forinelif in NEXTMONTH"
            self.year += 1
        self.split()


    def createDaysOfWeekLabels(self):
        days = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
        for i in range(7):
            label = Label(self, text=days[i], width = 3)
            label.grid(row = 2, column = i)

    def showMonth(self, mFrame, mButton):
        # Display all buttons normally
        for button in self.buttonList:
            button['relief'] = 'raised'

        # Set this month's button relief to flat
        mButton['relief'] = 'flat'

        # Hide all frames
        for mframe in self.frameList:
            mframe.grid_remove()

        mFrame.grid()

    def createMonth(self, mFrame):

        weekday, numDays = monthrange(self.year, self.month)
        week = 0
        for i in range(1, numDays + 1):
            button = Button(mFrame, text = str(i), width=3)
            button.grid(row = week, column = weekday)

            weekday += 1

            if weekday > 6:
                week += 1
                weekday = 0

mainWindow = Tk()
obj = Application(mainWindow)
mainWindow.mainloop()

答案 1 :(得分:0)

Tkinter效率很高。对于您拥有的小部件数量,最初创建它们不会对性能产生太大影响。这是一个与你试图做的一样的样本。

from calendar import *
import datetime
try:
    from tkinter import *   # Python 3.x
except:
    from Tkinter import *   # Python 2.x


class Application(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 - 1
        for i in range(3):
            if amonth < 0:
                amonth = 11
                year -= 1
            elif 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)


    def createDaysOfWeekLabels(self):
        days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
        for i in range(7):
            label = Label(self, text=days[i])
            label.grid(row = 1, column = i)

    def showMonth(self, mFrame, mButton):
        # Display all buttons normally
        for button in self.buttonList:
            button['relief'] = 'raised'

        # Set this month's button relief to flat
        mButton['relief'] = 'flat'

        # Hide all frames
        for frame in self.frameList:
            frame.grid_remove()

        mFrame.grid()

    def createMonth(self, mFrame, month, year):
        weekday, numDays = monthrange(year, month)
        week = 0
        for i in range(1, numDays + 1):
            button = Button(mFrame, text = str(i), width=3)
            button.grid(row = week, column = weekday)

            weekday += 1

            if weekday > 6:
                week += 1
                weekday = 0

mainWindow = Tk()
obj = Application(mainWindow)
mainWindow.mainloop()