Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 特金特网格重叠_Python_Tkinter - Fatal编程技术网

Python 特金特网格重叠

Python 特金特网格重叠,python,tkinter,Python,Tkinter,我正在创建一个日历,允许用户通过按上个月和下个月创建的按钮来循环月和年。基本上,我希望主窗口在单击“上一个月”或“下一个月”时使用正确的日期更新新的月份,它会这样做,唯一的问题是在循环时显示月份的特定日期重叠的日期按钮。 以下是我遇到的问题: def prevMonth(self): try: self.grid_forget() #SHOULD REFRESH THE WINDOW SO BUTTONS DONT OVERLAP

我正在创建一个日历,允许用户通过按上个月和下个月创建的按钮来循环月和年。基本上,我希望主窗口在单击“上一个月”或“下一个月”时使用正确的日期更新新的月份,它会这样做,唯一的问题是在循环时显示月份的特定日期重叠的日期按钮。 以下是我遇到的问题:

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返回函数没有destroy属性的错误。我已经尝试将网格的子项设置为self中的所有全局变量,但我无法正确迭代月份,因此设置是永久性的,但我觉得我缺少了一些简单的东西,比如刷新网格并根据更新的月份重新打印

你能给我指出正确的方向或纠正我遗漏的错误吗

下面是整个程序

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

特金特相当有效率。对于您拥有的小部件的数量,最初创建它们不会对性能产生太大影响。下面是一个示例,它的工作原理与您试图做的类似

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

这是建议答案的一个修改版本,其中还包括最初的预期意图,即允许用户循环几个月,并将增加一年

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

您只创建了一个帧。一旦您忘记了它,主窗口上就不再有GUI元素了。如果您继续在应用程序初始化期间构建GUI组件,然后隐藏/显示框架,那么您将通过init方法创建所有三个框架。然后你忘记了先前可见的帧,并对下一帧或上一帧进行网格化。我试图避免制作3个不同的窗口,而只是在用户循环使用tkinter时循环使用主窗口。。。我没有使用太多tkinter,所以我甚至不确定我是否正确使用了grid\u忘记self.destroy只创建了一个空白窗口-假设self是一个小部件,这是不可能的。销毁无法创建小部件。当我说创建时,我的意思是它会使窗口变为空白并抛出错误。这几乎是完美的!唯一的问题是你只有3个月的时间可以查看。。。对于此日历的最终结果,它必须能够根据需要在月份和年份之间循环,因为此应用程序的最终结果将是一个财务/票据跟踪器,并且3个月的跟踪有点有限。很容易将其扩展到所有12个月。只需增加init部分中的循环,以创建12个按钮和框架,而不是3个。这并不是我想要的,但你给了我修改解决方案所需的东西。对于UI的流动性,我希望保留3个月,并且只需要3个按钮就可以循环使用。因此,你从3月开始,2月和4月为上个月和下个月,当你从这两个月中选择一个月时,它们会转移到中心月,并相应地调整上个月和下个月。