Tkinter高级编程:掌握类与面向对象设计
这是文章《高级Tkinter:使用类进行操作》的第1部分(共4部分)。
今天,我们将深入探讨如何在Tkinter中使用类。如果你之前接触过Tkinter,你可能知道它提供了丰富的GUI功能来创建应用程序。
然而,在实际开发中,你很快会意识到Tkinter的复杂性远超表面。它隐藏着许多强大的功能,其中之一就是如何在模块中有效地利用类。
Tkinter模块安装
Tkinter是Python标准库的一部分,因此无需额外安装。但是,本文将涉及Tkinter的高级用法,建议读者先阅读Tkinter的基础系列教程。
在继续之前,请务必阅读以下Tkinter基础教程:
如果你已经完成了基础教程,那么让我们开始使用Tkinter模块吧!
为了使用类,我们需要导入Tkinter模块:
# 导入Tkinter模块
import tkinter as tk
# 用于GUI样式设计
from tkinter import ttk
为了方便起见,我们还将单独导入ttk
包,它提供了更现代的GUI组件。
在Tkinter中利用类进行开发
现在,让我们了解如何在Tkinter中运用类。我们将构建一个简单的应用程序,其工作方式如下:
首先,创建一个根窗口,并在其上放置一个独立的框架。为了模拟一个带有不同“窗口”的应用程序,我们还将实现一个功能,允许用户在不同的框架之间切换。
这会给用户一种错觉,认为他们正在被重定向到不同的窗口或标签页,但实际上只是在不同的框架之间进行切换。我们将使用的框架包括主页面、侧边页面和完成页面。
我们将使用show_frame()
方法来实现框架之间的切换。
开始编码:创建基类
让我们创建一个基类,所有其他类或窗体都将从这个基类继承,作为应用程序的起点。
# 允许从Tk类扩展
class testClass(tk.Tk):
从tk.Tk
类继承使我们能够使用Tk()
类中提供的所有组件和功能。
1. 类的初始化
这是文章《高级的Tkinter:使用类进行操作》的第2部分(共4部分)。
内容片段:为了初始化类,我们使用__init__
函数。这样可以创建一个在我们从类中生成对象时自动运行的方法。
以类似的方式,我们也通过tk.Tk.__init__
初始化类。
import tkinter as tk
from tkinter import ttk
class windows(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# 为窗口添加标题
self.wm_title("测试应用程序")
# 创建一个框架并将其分配给容器
container = tk.Frame(self, height=400, width=600)
# 指定框架在根窗口中的打包区域
container.pack(side="top", fill="both", expand=True)
# 使用grid配置容器的位置
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
# 我们现在将创建一个框架字典
self.frames = {}
# 我们稍后会创建框架本身,但现在先将组件添加到字典中。
for F in (MainPage, SidePage, CompletionScreen):
frame = F(container, self)
# windows类作为框架的根窗口。
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
# 使用方法切换框架
self.show_frame(MainPage)
2. 创建一种切换视图框架的方法。
这是文章《高级的Tkinter:使用类进行操作》的第3部分(共4部分)。
内容片段: 现在我们已经创建了__init__
方法,并指定了要使用的框架,我们可以创建一个方法来切换我们正在查看的框架。
def show_frame(self, cont):
frame = self.frames[cont]
# 将当前框架提升到顶部
frame.tkraise()
3. 为框架创建多个类。现在,我们创建不同的类作为框架,并通过 show_frame()
方法进行切换。
class MainPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="主页")
label.pack(padx=10, pady=10)
# 我们使用 switch_window_button 来调用 show_frame() 方法作为 lambda 函数
switch_window_button = tk.Button(
self,
text="前往侧边页",
command=lambda: controller.show_frame(SidePage),
)
switch_window_button.pack(side="bottom", fill=tk.X)
class SidePage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="这是侧边页")
label.pack(padx=10, pady=10)
switch_window_button = tk.Button(
self,
text="前往完成界面",
command=lambda: controller.show_frame(CompletionScreen),
)
switch_window_button.pack(side="bottom", fill=tk.X)
class CompletionScreen(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="完成界面,我们做到了!")
label.pack(padx=10, pady=10)
switch_window_button = ttk.Button(
self, text="返回菜单", command=lambda: controller.show_frame(MainPage)
)
switch_window_button.pack=(side="bottom", fill=tk.X)
如果你注意到了的话,这些类是通过 self.frames
变量添加到主类中的。
我将保留将类实现的命令放在 __name__ == "__main__"
中,但你也可以直接使用它。
if __name__ == "__main__":
testObj = windows()
testObj.mainloop()
继续前进
我们现在已经完成了定义类和方法的步骤,可以运行这个脚本了。
这应该会弹出一个小窗口,你只需点击一个按钮即可在不同的帧(frame)之间进行切换。
更进一步,你甚至可以在应用程序顶部的菜单栏中实现切换帧的功能。
结论
在Tkinter模块中使用类进行开发,为处理和创建新应用程序打开了许多机会。
我们今天处理了相当多的代码,为了确保我们都理解一致,以下是核心要点!
如果你希望查看一个现成的例子,请看看我的项目“艾森票务”(Eisen Ticketing),它实现了许多Tkinter的特性,包括类,并且使用SQLite3数据库运行。
参考资料
- Tkinter 文档
- Tkinter 类