2016-05-11 4 views
0

При реализации сложных диалогов (например, диалогов с 10 или более виджетами, особенно когда они расположены в нескольких кадрах и т. П.), Для создания требуется много вызовов tkinter, и код может стать все более сложным (трудно читать и поддерживать), когда он хранится в рамках одного метода. Также, как правило, короткие функции/методы обычно предпочтительнее более длинных.Python, tkinter, сложные диалоги и структура кода

Мой текущий подход ограничить длину метода является инкапсуляция создание всех виджетов, которые принадлежат к группе в диалоговом окне в один method(parent_frame, other_options), который возвращает виджет верхнего уровня, как это:

import tkinter as tk 

class Dialog: 
    def __init__(self, master): 
     self.__master = master 
     self.create_gui(master) 

    def create_gui(self, frame, title = None): 
     if title: frame.title(title) 

     group_a = self.create_group_a(frame) 
     group_a.grid(row=0, column=0, sticky="nsew") 

     group_b = self.create_group_b(frame) 
     group_b.grid(row=1, column=0, sticky="nsew") 

     frame.columnconfigure(0, weight=1) 
     frame.rowconfigure(0, weight=1) 
     frame.rowconfigure(1, weight=1) 

    def create_group_a(self, frame): 
     inner_frame = tk.LabelFrame(frame, text="Label") 
     text = self.create_text_with_scrollbar(inner_frame) 
     text.pack(fill="both") 
     return inner_frame 

    def create_group_b(self, frame): 
     button = tk.Button(frame, text="Button") 
     return button 

    def create_text_with_scrollbar(self, frame): 
     text_frame = tk.Frame(frame) 
     text_frame.grid_rowconfigure(0, weight=1) 
     text_frame.grid_columnconfigure(0, weight=1) 

     text = tk.Text(text_frame) 
     text.grid(row=0, column=0, sticky="nsew") 

     scrollbar = tk.Scrollbar(text_frame, command=text.yview) 
     scrollbar.grid(row=0, column=1, sticky="nsew") 
     text['yscrollcommand'] = scrollbar.set 

     return text_frame 


if __name__ == "__main__": 
    master = tk.Tk() 
    Dialog(master) 
    tk.mainloop() 

Существуют ли какие-либо конкретные рекомендации по структурированию кода в таких случаях? Кто-нибудь знает, как лучше структурировать такой код?

ответ

2

Что я обычно делаю, так это написать новый класс для каждой группы. Эти классы наследуют от Frame. Конечный результат будет выглядеть примерно так:

class MainFrame(Frame): 
    def __init__(self, *args, **kwargs): 
     super().__init__(self, *args, **kwargs) 
     self.first_sub = FirstSubFrame(self) 
     self.second_sub = SecondSubFrame(self) 

     self.first_sub.grid() 
     self.second_sub.grid() 


class FirstSubFrame(Frame): 
    def __init__(self, *args, **kwargs): 
     super().__init__(self, *args, **kwargs) 
     self.possibly_another_subframe = PossibleOtherFrame(self) 
     self.awesome_button = tkinter.Button() 

     self.possibly_another_subframe.grid() 
     self.awesome_button.grid() 

... 

Я надеюсь, что это помогает.

+0

Спасибо! Брайан Оукли также наследует свои классы из классов Tkinter в http://stackoverflow.com/questions/17466561/best-way-to-structure-a-tkinter-application. Однако есть комментарий к его ответу (от Shule), в котором говорится, что в некоторых случаях лучше не наследовать от Frame и т. Д., А скорее иметь член кадра. Моя интуиция говорит мне то же самое, но я не могу объяснить, почему. Это было одной из причин, чтобы задать вопрос в первую очередь. Я уточню вопрос. – Robin

+0

Нет, я не буду обновлять вопрос. Вопрос «наследование от классов tkinter или нет» - это тема сама по себе, которая обсуждалась, например. здесь: http://stackoverflow.com/questions/7300072/inheriting-from-frame-or-not-in-a-tkinter-application. – Robin

Смежные вопросы