日历应用

时间:2018-04-06 03:23:04

标签: python user-interface calendar

我正在为我的计算机制作一个非常基本的日历应用程序来练习使用GUI并使它们与代码交互。我的第一个问题围绕着日历的间距。这是我的代码(功能齐全,没有错误):

from tkinter import *
from tkinter import ttk
import calendar


class main:
    def __init__(self, master):
        self.master = master
        self.month = IntVar()
        self.year = IntVar()
        self.months = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
        self.widgets()

    def getcal(self):
        # Day/Month/Year Computations
        m = self.month.get()
        y = self.month.get()

        # Horizontal/Vertical Spacing for Formatting Calendar Output
        cal = calendar.month(y,m,1,1)
        self.area.delete(0.0, END)
        self.area.insert(0.0, cal)

    def widgets(self):
        # Main Heading
        Label(self.master, text='Calendar', font=('freesansbold', 30), bd=10).pack()
        f = Frame(self.master, pady = 10, padx=10)

        # Month Label:
        Label(f, text='Month: ', font=('freesansbold', 13)).grid()

        # Month Dropdown Selector
        mon = ttk.Combobox(f, width=7, font=('freesansbold', 15), values=self.months, textvariable = self.month)
        mon.grid(row=0, column=1)
        mon.current(0)

        # Year Label:
        Label(f, text='Year: ', font=('freesansbold', 13)).grid(row=0, column=2)

        # Year Entry Box:
        ttk.Entry(f, width=7, font = ('freesansbold', 13), textvariable=self.year).grid(row=0, column=3)
        f.pack()

        # Calendar Display area:
        self.area = Text(self.master, font=('freesansbold', 15, 'bold'), width=20, height=9, bd=15)
        self.area.pack()

        # Get Calendar button
        Button(self.master, command = self.getcal, text='Get Calendar', font=('freesansbold', 15, 'bold'), bd=10).pack()


if __name__ == '__main__':
    root = Tk()
    main(root)
    root.title('Calendar')
    root.mainloop()

所以第一个问题是,我如何将日期数字与一周中的日期对齐? (我通常把这一年当作2010年,因为它从星期一开始这个月)目前的方式,数字完全被抛弃,我对它的外观有点挑剔。第二个问题可能会回答这个问题:

第二个问题: 如何让每个月的每一天都成为按钮?我真的不想输入这个代码31次以获得正确的网格间距,即复制按钮代码和更改网格数字。什么是一个很好的算法来创建我需要的所有按钮,并在它们上投射正确的数字?我玩过这个,除了一遍又一遍地输入这些东西之外我什么都没找到。

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:-1)

要让每一天都成为按钮,您就会想要停止使用Text小部件。

日历模块有一个名为calendar.monthcalendar的有用函数,它在矩阵(嵌套列表)中返回特定月份的日历。如果您生成按钮矩阵,则可以使用monthcalendar的输出填充正确位置的数字:

from tkinter import *
from tkinter import ttk
import calendar


class main:
    def __init__(self, master):
        self.master = master
        self.month = IntVar()
        self.year = IntVar()
        self.months = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
        self.widgets()

    def getcal(self):
        # Day/Month/Year Computations
        m = self.month.get()
        y = self.year.get()

        # Fill current month label
        self.current['text'] = calendar.month_name[m] + ' ' + str(y)

        # Remove text from all buttons
        for ii in range(6):
            for jj in range(7):
                self.area[ii][jj]['text'] = ''

        # Loop over monthcalendar matrix and fill button text
        for ii, week in enumerate(calendar.monthcalendar(y, m)):
            for jj, day in enumerate(week):
                if day != 0:
                    self.area[ii][jj]['text'] = day

    def click(self, event):
        print(event.widget.cget('text'))

    def widgets(self):
        # Main Heading
        Label(self.master, text='Calendar', font=('freesansbold', 30), bd=10).pack()
        f = Frame(self.master, pady = 10, padx=10)

        # Month Label:
        Label(f, text='Month: ', font=('freesansbold', 13)).grid()

        # Month Dropdown Selector
        mon = ttk.Combobox(f, width=7, font=('freesansbold', 15), values=self.months, textvariable = self.month)
        mon.grid(row=0, column=1)
        mon.current(0)

        # Year Label:
        Label(f, text='Year: ', font=('freesansbold', 13)).grid(row=0, column=2)

        # Year Entry Box:
        ttk.Entry(f, width=7, font = ('freesansbold', 13), textvariable=self.year).grid(row=0, column=3)
        self.year.set(2010)
        f.pack()

        # Label for currently displayed month
        self.current = Label(self.master, text='', font=('freesansbold', 13))
        self.current.pack()

        # Calendar Display area:
        f2 = Frame(self.master, pady = 10, padx=10)

        # Add day indicators
        for i, day in enumerate(calendar.day_abbr):
            Label(f2, text=day, font=('freesansbold', 13)).grid(row=0, column=i)

        # Create empty matrix
        self.area = [ [ 0 for i in range(7) ] for j in range(6) ]
        # Fill matrix with buttons
        for ii in range(6):
            for jj in range(7):
                self.area[ii][jj] = Button(f2, text='', font=('freesansbold', 15, 'bold'), width=4, height=1, bd=0)
                self.area[ii][jj].bind("<Button-1>", self.click)
                self.area[ii][jj].grid(row=ii+1, column=jj)

        f2.pack()

        # Get Calendar button
        Button(self.master, command = self.getcal, text='Get Calendar', font=('freesansbold', 15, 'bold'), bd=10).pack()


if __name__ == '__main__':
    root = Tk()
    main(root)
    root.title('Calendar')
    root.mainloop()

P.S。您使用了y = self.month.get()代替y = self.year.get(),这使您的函数使用了当年的月份数(1-12)。