使用Tkinter构建GUI日历
在Python中构建项目非常令人兴奋。Python提供了不同的模块和库来使项目具有交互性。其中一个特性是图形用户界面(GUI),可以使用Python库如Tkinter、PyQt5、Kivy等将其添加到项目中。Tkinter库是用于设计交互式GUI应用程序的最常见库之一。它轻巧且易于使用。我们可以在不同的平台或操作系统上运行此库,如Windows、Linux和macOS。
在以下教程中,我们将学习如何使用Python编程语言中的Tkinter库构建基于GUI的日历。
那么,让我们开始吧。
使用Tkinter构建GUI日历
为了开始在Python中构建GUI日历,我们将考虑按照下面所示的过程:
步骤1: 我们将导入所需的库和模块。
步骤2: 然后,我们将定义执行应用程序所必需的函数。
步骤3: 然后,我们将创建应用程序的主窗口。
步骤4: 我们将向主窗口添加小部件并应用事件触发。
现在让我们详细了解上述步骤。
导入所需的库和模块
首先,我们将导入必要的库和模块,包括 tkinter 库以添加GUI到应用程序中,从 PIL 库导入 ImageTk 和 Image 模块以将图像添加到应用程序中,从 calendar 模块获取年份数据,以及从 datetime 模块中导入日期模块以获取当前月份和年份。
让我们考虑以下示例代码片段来演示以上内容。
文件:guiCalendar.py
# importing the required libraries and modules
from tkinter import * # importing all methods, classes and widgets from the tkinter library
from PIL import ImageTk, Image # importing the ImageTk and Image modules from the PIL library
import calendar # importing the calendar module
from datetime import date # importing the date module from the datetime library
解释:
在上面的代码片段中,我们从 tkinter 库中导入所有的方法、类和小部件。然后我们从 ImageTk 和 Image 模块中导入 PIL 库。然后我们导入了 calendar 模块。最后,我们从 datetime 库中导入了 date 模块。
定义应用程序的函数
一旦我们导入了所需的库和模块,我们将向程序中添加一些函数来执行特定的功能并与应用程序交互。这些函数将向用户显示数据,重置输入并关闭应用程序。
我们将首先定义第一个函数来显示日历。现在让我们来看以下演示相同功能的代码片段。
文件: guiCalendar.py
# defining the necessary functions
# function to display the Calendar
def displayCalendar():
# get the month and year data from the spin boxes
month = int(month_box.get())
year = int(year_box.get())
# using the month() method from the calendar module to
# get the month info and storing in the variable
output_calendar = calendar.month(year, month)
# using the delete() method to delete the output
calendar_field.delete(1.0, 'end')
# displaying the resultant calendar
calendar_field.insert('end', output_calendar)
解释:
在上述代码片段中,我们定义了一个名为displayCalendar的函数。这个函数允许我们打印指定月份和年份的日历。我们从旋钮框中获取了月份和年份的数据,并将它们存储为不同的变量的整数值,分别是month和year。然后,我们使用calendar模块中的month()方法检索月份的详细信息,并将其存储在另一个变量output_calendar中。我们使用delete()方法删除了文本字段中先前的输出。最后,我们使用insert()方法将生成的日历插入到文本字段中。
让我们现在定义另一个函数来重置应用程序中的数值和结果。以下是演示相同的代码片段。
文件:guiCalendar.py
# function to reset the entries
def reset():
# using the delete() method to delete the output
calendar_field.delete(1.0, 'end')
# setting the values of the IntVar objects to current month and year
month_var.set(current_month)
year_var.set(current_year)
# using the config() method and assigning the
# textvariable parameter to different IntVar objects
month_box.config(textvariable = month_var)
year_box.config(textvariable = year_var)
解释:
在上面的代码片段中,我们定义了一个名为 reset 的函数。在这个函数中,我们使用 delete() 方法来删除文本字段中的输出。然后,我们将 IntVar 对象的值设置为当前的月份和年份。接着,我们使用 config() 方法对 spinbox 对象进行配置,并将它们的 textvariable 参数的值设为上述的 IntVar 对象。
现在,我们将定义另一个函数来关闭应用程序。让我们考虑下面的代码片段来演示相同的功能。
文件:guiCalendar.py
# function to close the application
def close():
# using the destroy() method to close the application
guiWindow.destroy()
解释:
在上面的代码片段中,我们定义了一个名为close的函数。在这个函数内部,我们使用了Tk()类的destroy()方法来关闭应用程序。
创建应用程序的主窗口
我们将创建应用程序的主窗口,以显示所有的小部件和用户的输出。我们首先创建一个Tkinter库的Tk()类的对象。然后,我们设置标题、大小、位置、背景颜色和位图图标,使其看起来有吸引力。
现在让我们考虑以下演示相同功能的代码片段。
文件:guiCalendar.py
# main function
if __name__ == "__main__":
# creating an object of the Tk() class
guiWindow = Tk()
# setting the title for the main window
guiWindow.title("GUI Calendar - JAVATPOINT")
# setting the size and position of the main window
guiWindow.geometry('500x550+650+250')
# disabling the resizable option
guiWindow.resizable(0, 0)
# setting the background color to #B0E0E6
guiWindow.configure(bg="#B0E0E6")
# setting the bitmap icon for the application
guiWindow.iconbitmap("icon_calendar.ico")
解释:
在上面的代码片段中,我们创建了一个 Tk() 类的对象,该对象将表示应用程序的主窗口。然后,我们使用 title() 方法设置主窗口的标题。我们还使用 geometry() 方法设置了主窗口的大小和位置,并通过将 resizable() 方法的参数设置为 0 来禁用了可调整大小的选项。我们还使用 configure() 方法设置了背景颜色,并使用 iconbitmap() 方法设置了位图图标。我们使用 ICO 文件导入了应用程序中的图标图像。
向主窗口添加小部件并应用事件触发器
我们现在将向主窗口添加一些小部件,包括框架以为其他小部件提供适当的结构、标签以在应用程序中显示信息、微调框以输入月份和年份的详细信息、文本字段以显示输出以及一些按钮以触发具体事件。
我们将从向应用程序添加框架开始。这些框架将帮助我们提供一个明确定义的结构来容纳其他小部件。我们将使用 Frame() 小部件来创建一个。
让我们考虑以下代码片段,演示相同的内容。
文件:guiCalendar.py
# creating the objects of the Frame() widget
header_frame = Frame(guiWindow, bg = "#B0E0E6")
entry_frame = Frame(guiWindow, bg = "#B0E0E6")
result_frame = Frame(guiWindow, bg = "#B0E0E6")
button_frame = Frame(guiWindow, bg = "#B0E0E6")
# using the pack() method to set the positions of the frames
header_frame.pack(expand = True, fill = "both")
entry_frame.pack(expand = True, fill = "both")
result_frame.pack(expand = True, fill = "both")
button_frame.pack(expand = True, fill = "both")
解释:
在上面的代码片段中,我们使用 Frame() 小部件创建了一些帧,并将它们的 master 参数设置为 Tk() 类的对象,即 guiWindow 。我们将它们的背景颜色设置为 bg 参数为 #B0E0E6 。然后,我们使用 pack() 方法在应用程序中设置了帧的位置。我们将 expand 参数设置为 True ,将 fill 参数设置为 both ,以便帧可以在提供的空间的两侧扩展。
现在我们将向应用程序中添加不同的标签。我们将首先创建一个显示标题的标签,然后创建另一个用于显示图像的标签。我们还将添加两个标签来显示月份和年份信息。我们将使用 Label() 小部件来创建这些标签。
让我们来看一下下面的代码片段,演示了每个标签的创建。
文件:guiCalendar.py
# creating the label to display the heading
header_label = Label(
header_frame,
text = "CALENDAR",
font = ('verdana','25','bold'),
bg = "#B0E0E6",
fg = "#191970"
)
# using the pack() method to set the position of the label
header_label.pack(expand = True, fill = "both")
说明:
在上面的代码片段中,我们使用了 Label() 方法来创建一个标签来显示标题。我们设置了该标签的 master 参数为 header_frame 。我们还设置了文本、字体样式和大小、背景颜色和前景颜色。然后我们使用了 pack() 方法来设置标签的位置。
文件:guiCalendar.py
# importing the image for the application
calendar_image = ImageTk.PhotoImage(Image.open('calendar.png').resize((50, 50), Image.ANTIALIAS))
# creating the label to display the imported image
image_label = Label(
header_frame,
image = calendar_image,
bg = "#B0E0E6"
)
# using the pack() method to set the position of the label
image_label.pack(expand = True, fill = "both")
解释:
在上面的代码片段中,我们使用了 open() 方法从目录中导入一张图片。然后我们使用了 resize() 方法来调整图片的大小,使其适应应用程序。我们还使用了 ANTIALIAS 滤波器对图像进行处理。然后,我们使用了 PhotoImage() 方法将导入的图片与Tkinter兼容起来,这是通过ImageTk模块实现的。然后,我们使用 Label() 小部件创建一个标签,用于显示导入的图片。我们将该小部件的 master 参数设置为 header_frame 框架。我们还将该标签的 image 参数设置为导入的图片。最后,我们使用 pack() 方法将该标签定位在主窗口上。
文件:guiCalendar.py
# creating the labels to display the details for the month and year
month_label = Label(
entry_frame,
text = "Month:",
font = ("consolas", "10", "bold"),
bg = "#B0E0E6",
fg = "#000000"
)
year_label = Label(
entry_frame,
text = "Year:",
font = ("consolas", "10", "bold"),
bg = "#B0E0E6",
fg = "#000000"
)
# using the place() method to set the position of the labels
month_label.place(x = 120, y = 0)
year_label.place(x = 268, y = 0)
说明:
在上面的代码片段中,我们使用 Label() 方法创建了两个标签,用于显示使用 Spinbox() 输入月份和年份的详细信息。 对于这些标签,我们已将 主 参数设置为 entry_frame 框架。我们还设置了文本、字体大小和样式、背景颜色和前景颜色。 然后,我们使用 place() 方法将这些标签的位置设置在主窗口上。
现在,我们已经添加了应用程序所需的所有标签,是时候创建一些用于输入数据的微调框了。 我们将使用 Spinbox() 小部件创建微调框。但是,在此之前,我们将创建 IntVar 类的对象。 当执行应用程序时,这些对象将存储当前月份和年份的值,并在微调框中显示它们。
让我们考虑以下演示相同情况的代码片段。
文件:guiCalendar.py
# creating the objects of the IntVar class
month_var = IntVar(entry_frame)
year_var = IntVar(entry_frame)
# storing the current month and year information
current_month = date.today().month
current_year = date.today().year
# setting the current month and year to the IntVar objects
month_var.set(current_month)
year_var.set(current_year)
# creating the spin boxes to enter month and year
month_box = Spinbox(
entry_frame,
from_ = 1,
to = 12,
width = "5",
textvariable = month_var
)
year_box = Spinbox(
entry_frame,
from_ = 0000,
to = 3000,
width = "5",
textvariable = year_var
)
# using the place() method to set the position of the spin boxes
month_box.place(x = 180, y = 0)
year_box.place(x = 320, y = 0)
解释:
在上面的代码片段中,我们创建了一些IntVar
类的对象,并将它们的master
参数设置为entry_frame
帧。然后,我们使用today()
方法来获取当前日期,使用month
和year
属性来获取当前月份和年份,并将它们存储在单独的变量中。然后,我们使用set()
方法将这些值设置在IntVar
类的对象中。然后,我们使用Spinbox()
小部件创建旋转框来输入月份和年份。我们将master
参数设置为entry_frame
帧。我们还设置了这些旋转框的范围和宽度。我们还使用textvariable
参数将这些旋转框的初始值设置为当前月份和存储在IntVar
类的对象中的变量。最后,我们使用place()
方法来设置这些旋转框的位置。
现在,我们将使用Text()
小部件创建一个文本框。该文本框将显示日历。
让我们考虑以下演示相同功能的代码片段。
文件:guiCalendar.py
# creating a textbox to display calendar
calendar_field = Text(
result_frame,
width = 20,
height= 8,
font = ("consolas", "14"),
relief = RIDGE,
borderwidth = 2
)
# using the pack() method to set the position of the textbox
calendar_field.pack(expand = False, fill = None)
说明:
在上面的代码片段中,我们使用了 Text() 小部件来创建显示日历的文本框。我们将 master 参数设置为 result_frame 框架,将 widget 和 height 参数分别设置为 20 和 8 。我们还设置了文本的字体样式和大小。我们还使用了 relief 参数将边框类型设置为 RIDGE ,并将 borderwidth 参数设置为 2 。最后,我们使用 pack() 方法设置文本框的位置。
现在,我们将向应用程序中添加一些按钮,这些按钮将允许我们显示日历、重置输入和输出,并关闭应用程序。可以使用 Button() 小部件创建这些按钮。我们还将在此小部件中使用 command 参数,并调用之前创建的函数。
让我们考虑以下代码片段来演示相同的功能。
文件:guiCalendar.py
# creating the buttons for the application
# DISPLAY BUTTON
display_button = Button(
button_frame,
text = "DISPLAY",
bg = "#191970",
fg = "#E0FFFF",
command = displayCalendar
)
# RESET BUTTON
reset_button = Button(
button_frame,
text = "RESET",
bg = "#191970",
fg = "#E0FFFF",
command = reset
)
# CLOSE BUTTON
close_button = Button(
button_frame,
text = "CLOSE",
bg = "#191970",
fg = "#E0FFFF",
command = close
)
# using the place() method to set the positions of the buttons
display_button.place(x = 140, y = 0)
reset_button.place(x = 230, y = 0)
close_button.place(x = 305, y = 0)
解释:
在上面的代码片段中,我们使用了 Button() 小部件,并为应用程序创建了一些按钮。我们将这些小部件的 master 参数设置为 button_frame 帧。我们还设置了必要的文本、背景颜色和前景颜色。然后,我们使用 command 参数将其值设置为我们之前定义的函数,在点击时会被调用。最后,我们使用 place() 方法来设置按钮的位置。
现在,我们将使用 mainloop() 方法以 Tk() 类的对象来运行应用程序。以下是展示相同的代码片段。
文件:guiCalendar.py
# using the mainloop() method to run the application
guiWindow.mainloop()
解释:
在上面的代码片段中,我们使用了 mainloop() 方法,以及 guiWindow ,这是 Tk() 类的对象。
因此,项目代码现在已经完成。我们可以保存文件并在命令行或终端中运行以下命令来查看输出。
语法:
$ python guiCalendar.py
在我们看到输出之前,让我们考虑一下Python中“GUI Calendar”项目的完整代码。
完整的项目代码
以下是Python编程语言中“GUI Calendar”项目的代码片段。
文件:guiCalendar.py
# importing the required libraries and modules
from tkinter import * # importing all methods, classes and widgets from the tkinter library
from PIL import ImageTk, Image # importing the ImageTk and Image modules from the PIL library
import calendar # importing the calendar module
from datetime import date # importing the date module from the datetime library
# defining the necessary functions
# function to display the Calendar
def displayCalendar():
# get the month and year data from the spin boxes
month = int(month_box.get())
year = int(year_box.get())
# using the month() method from the calendar module to
# get the month info and storing in the variable
output_calendar = calendar.month(year, month)
# using the delete() method to delete the output
calendar_field.delete(1.0, 'end')
# displaying the resultant calendar
calendar_field.insert('end', output_calendar)
# function to reset the entries
def reset():
# using the delete() method to delete the output
calendar_field.delete(1.0, 'end')
# setting the values of the IntVar objects to current month and year
month_var.set(current_month)
year_var.set(current_year)
# using the config() method and assigning the
# textvariable parameter to different IntVar objects
month_box.config(textvariable = month_var)
year_box.config(textvariable = year_var)
# function to close the application
def close():
# using the destroy() method to close the application
guiWindow.destroy()
# main function
if __name__ == "__main__":
# creating an object of the Tk() class
guiWindow = Tk()
# setting the title for the main window
guiWindow.title("GUI Calendar - JAVATPOINT")
# setting the size and position of the main window
guiWindow.geometry('500x550+650+250')
# disabling the resizable option
guiWindow.resizable(0, 0)
# setting the background color to #B0E0E6
guiWindow.configure(bg="#B0E0E6")
# setting the bitmap icon for the application
guiWindow.iconbitmap("icon_calendar.ico")
# creating the objects of the Frame() widget
header_frame = Frame(guiWindow, bg = "#B0E0E6")
entry_frame = Frame(guiWindow, bg = "#B0E0E6")
result_frame = Frame(guiWindow, bg = "#B0E0E6")
button_frame = Frame(guiWindow, bg = "#B0E0E6")
# using the pack() method to set the positions of the frames
header_frame.pack(expand = True, fill = "both")
entry_frame.pack(expand = True, fill = "both")
result_frame.pack(expand = True, fill = "both")
button_frame.pack(expand = True, fill = "both")
# creating the label to display the heading
header_label = Label(
header_frame,
text = "CALENDAR",
font = ('verdana','25','bold'),
bg = "#B0E0E6",
fg = "#191970"
)
# using the pack() method to set the position of the label
header_label.pack(expand = True, fill = "both")
# importing the image for the application
calendar_image = ImageTk.PhotoImage(Image.open('calendar.png').resize((50, 50), Image.ANTIALIAS))
# creating the label to display the imported image
image_label = Label(
header_frame,
image = calendar_image,
bg = "#B0E0E6"
)
# using the pack() method to set the position of the label
image_label.pack(expand = True, fill = "both")
# creating the labels to display the details for the month and year
month_label = Label(
entry_frame,
text = "Month:",
font = ("consolas", "10", "bold"),
bg = "#B0E0E6",
fg = "#000000"
)
year_label = Label(
entry_frame,
text = "Year:",
font = ("consolas", "10", "bold"),
bg = "#B0E0E6",
fg = "#000000"
)
# using the place() method to set the position of the labels
month_label.place(x = 120, y = 0)
year_label.place(x = 268, y = 0)
# creating the objects of the IntVar class
month_var = IntVar(entry_frame)
year_var = IntVar(entry_frame)
# storing the current month and year information
current_month = date.today().month
current_year = date.today().year
# setting the current month and year to the IntVar objects
month_var.set(current_month)
year_var.set(current_year)
# creating the spin boxes to enter month and year
month_box = Spinbox(
entry_frame,
from_ = 1,
to = 12,
width = "5",
textvariable = month_var
)
year_box = Spinbox(
entry_frame,
from_ = 0000,
to = 3000,
width = "5",
textvariable = year_var
)
# using the place() method to set the position of the spin boxes
month_box.place(x = 180, y = 0)
year_box.place(x = 320, y = 0)
# creating a textbox to display calendar
calendar_field = Text(
result_frame,
width = 20,
height= 8,
font = ("consolas", "14"),
relief = RIDGE,
borderwidth = 2
)
# using the pack() method to set the position of the textbox
calendar_field.pack(expand = False, fill = None)
# creating the buttons for the application
# DISPLAY BUTTON
display_button = Button(
button_frame,
text = "DISPLAY",
bg = "#191970",
fg = "#E0FFFF",
command = displayCalendar
)
# RESET BUTTON
reset_button = Button(
button_frame,
text = "RESET",
bg = "#191970",
fg = "#E0FFFF",
command = reset
)
# CLOSE BUTTON
close_button = Button(
button_frame,
text = "CLOSE",
bg = "#191970",
fg = "#E0FFFF",
command = close
)
# using the place() method to set the positions of the buttons
display_button.place(x = 140, y = 0)
reset_button.place(x = 230, y = 0)
close_button.place(x = 305, y = 0)
# using the mainloop() method to run the application
guiWindow.mainloop()
输出: