Я пишу программу на Python с графическим интерфейсом и выбрал tkinter для этого.У меня есть некоторый опыт работы с Python, но я новичок в программировании на tkinter и GUI.
Я читал несколько уроков о том, как использовать tkinter.То, что я мог найти, было очень простым, например, «как отобразить кнопку».Это заставляет меня изо всех сил пытаться найти полезную модель для структурирования части моей программы, которая определяет пользовательский интерфейс.
До сих пор в результате моих поисков было получено только 1 руководство по структурированию графического интерфейса Python / tkinter в стиле ООП: pythonprogramming.net
Хотя это отрадный пример и очень полезен в своей специфике, мне кажется, что наследование классов tkinter и добавление нового несвязанного кода в эти новые классы нарушает строгое разделениепроблемы.Это выглядит очень удобно в краткосрочной перспективе, но я не могу сказать, имеет ли это нежелательные последствия в долгосрочной перспективе.
В качестве альтернативы я создал другой пример, в котором я сделал аналогичные классы, но избегал наследования от tkinterклассы, составляя различные объекты tkinter.Это позволяет отделить функциональность лишь несколькими дополнительными методами.
Буду признателен за отзыв о том, какой подход более полезен, когда пользовательский интерфейс усложняется.Это может включать конкретные предложения по использованию других моделей, ссылки на информацию по теме, примеры исходного кода программ, использующих 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: Добавить сеточную переменную на страницу init
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()