【发布时间】:2019-06-15 13:44:00
【问题描述】:
我正在编写一个带有 GUI 的 Python 程序,并选择了 tkinter 来执行此操作。我对 Python 有一些经验,但我是 tkinter 和 GUI 编程的新手。
我一直在阅读一些关于如何使用 tkinter 的教程。我能找到的是非常基本的,例如“如何显示按钮”。这让我很难找到一个有用的模型来构建我的程序中定义 UI 的部分。
到目前为止,我的搜索只找到了 1 个以 OOP 样式构建 python/tkinter GUI 的指南:pythonprogramming.net
虽然这是一个受欢迎的例子,并且对它的特殊性很有帮助,但在我看来,tkinter 类的继承和向这些新类添加新的不相关代码违反了严格的关注点分离。短期看来很方便,但长期看会不会有不良后果。
作为替代方案,我创建了另一个示例,在其中我创建了类似的类,但通过组合各种 tkinter 对象来避免从 tkinter 类继承。这使功能与仅几个额外的方法分开。
如果 UI 变得越来越复杂,我希望得到反馈,了解哪种方法更有用。这可能包括对要使用的其他模型的具体建议、主题信息的链接、使用 tkinter 的程序的源代码示例等等。
基于pythonprogramming.net的继承示例:
import tkinter as tk
class AppMain(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
frame = Page(container, self)
self.frames[Page] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(Page)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class Page(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Start Page", font=("Verdana", 12))
label.pack(padx=10, pady=10)
def main():
application = AppMain()
application.mainloop()
if __name__ == "__main__":
main()
没有继承的替代方案:
编辑 1:将网格变量添加到页面初始化
import tkinter as tk
class AppMain(object):
def __init__(self):
self.root = tk.Tk()
container = tk.Frame(self.root)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.pages = {}
page = Page(container, self.root, {"row": 0, "column": 0, "sticky": "nsew"})
self.pages[Page] = page
self.show_page(Page)
def show_page(self, container):
page = self.pages[container]
page.show()
def run(self):
self.root.mainloop()
class Page(object):
def __init__(self, parent, controller, grid):
self.frame = tk.Frame(parent)
self.frame.grid(**grid)
label = tk.Label(self.frame, text="Start Page", font=("Verdana", 12))
label.pack(padx=10, pady=10)
def show(self):
self.frame.tkraise()
def main():
application = AppMain()
application.run()
if __name__ == "__main__":
main()
【问题讨论】:
标签: python-3.x oop tkinter