2013-05-08 2 views
3

Мне нужно понять концепцию метода модели/представления/контроллера и как написать такой графический интерфейс. Вот просто простой и простой графический интерфейс. Может кто-нибудь объяснить мне, как переписать этот код с помощью MVC?Как создать графический интерфейс с использованием метода model/view/controller?

from tkinter import * 

class Application(Frame): 
    """ GUI application that creates a story based on user input. """ 
    def __init__(self, master): 
     """ Initialize Frame. """ 
     super(Application, self).__init__(master) 
     self.grid() 
     self.create_widgets() 

    def create_widgets(self): 
     """ Create widgets to get story information and to display story. """ 
     # create instruction label 
     Label(self, 
       text = "Enter information for a new story" 
      ).grid(row = 0, column = 0, columnspan = 2, sticky = W) 

     # create a label and text entry for the name of a person 
     Label(self, 
       text = "Person: " 
      ).grid(row = 1, column = 0, sticky = W) 
     self.person_ent = Entry(self) 
     self.person_ent.grid(row = 1, column = 1, sticky = W) 

     # create a label and text entry for a plural noun 
     Label(self, 
       text = "Plural Noun:" 
      ).grid(row = 2, column = 0, sticky = W) 
     self.noun_ent = Entry(self) 
     self.noun_ent.grid(row = 2, column = 1, sticky = W) 

     # create a label and text entry for a verb 
     Label(self, 
       text = "Verb:" 
      ).grid(row = 3, column = 0, sticky = W) 
     self.verb_ent = Entry(self) 
     self.verb_ent.grid(row = 3, column = 1, sticky = W) 

     # create a label for adjectives check buttons 
     Label(self, 
       text = "Adjective(s):" 
      ).grid(row = 4, column = 0, sticky = W) 

     # create itchy check button 
     self.is_itchy = BooleanVar() 
     Checkbutton(self, 
        text = "itchy", 
        variable = self.is_itchy 
        ).grid(row = 4, column = 1, sticky = W) 

     # create joyous check button 
     self.is_joyous = BooleanVar() 
     Checkbutton(self, 
        text = "joyous", 
        variable = self.is_joyous 
        ).grid(row = 4, column = 2, sticky = W) 

     # create electric check button 
     self.is_electric = BooleanVar() 
     Checkbutton(self, 
        text = "electric", 
        variable = self.is_electric 
        ).grid(row = 4, column = 3, sticky = W) 

     # create a label for body parts radio buttons 
     Label(self, 
       text = "Body Part:" 
      ).grid(row = 5, column = 0, sticky = W) 

     # create variable for single, body part 
     self.body_part = StringVar() 
     self.body_part.set(None) 

     # create body part radio buttons 
     body_parts = ["bellybutton", "big toe", "medulla oblongata"] 
     column = 1 
     for part in body_parts: 
      Radiobutton(self, 
         text = part, 
         variable = self.body_part, 
         value = part 
         ).grid(row = 5, column = column, sticky = W) 
      column += 1 

     # create a submit button 
     Button(self, 
       text = "Click for story", 
       command = self.tell_story 
       ).grid(row = 6, column = 0, sticky = W) 

     self.story_txt = Text(self, width = 75, height = 10, wrap = WORD) 
     self.story_txt.grid(row = 7, column = 0, columnspan = 4) 

    def tell_story(self): 
     """ Fill text box with new story based on user input. """ 
     # get values from the GUI 
     person = self.person_ent.get() 
     noun = self.noun_ent.get() 
     verb = self.verb_ent.get() 
     adjectives = "" 
     if self.is_itchy.get(): 
      adjectives += "itchy, " 
     if self.is_joyous.get(): 
      adjectives += "joyous, " 
     if self.is_electric.get(): 
      adjectives += "electric, " 
     body_part = self.body_part.get() 

     # create the story 
     story = "The famous explorer " 
     story += person 
     story += " had nearly given up a life-long quest to find The Lost City of " 
     story += noun.title() 
     story += " when one day, the " 
     story += noun 
     story += " found " 
     story += person + ". " 
     story += "A strong, " 
     story += adjectives 
     story += "peculiar feeling overwhelmed the explorer. " 
     story += "After all this time, the quest was finally over. A tear came to " 
     story += person + "'s " 
     story += body_part + ". " 
     story += "And then, the " 
     story += noun 
     story += " promptly devoured " 
     story += person + ". " 
     story += "The moral of the story? Be careful what you " 
     story += verb 
     story += " for." 

     # display the story         
     self.story_txt.delete(0.0, END) 
     self.story_txt.insert(0.0, story) 

# main 
def main(): 
    root = Tk() 
    root.title("Mad Lib") 
    app = Application(root) 
    root.mainloop() 

main() 
+0

Ваш код содержит только «вид». У него нет моделей и контроллеров. –

+0

@SimeonVisser - Хорошо, как я могу их добавить? Что мне нужно сделать? –

+0

@IvanLesiv: Вам нужен немного более сложный пример, где у вас есть какие-то объекты или данные для моделирования, прежде чем дизайн MVC для вашего примера будет иметь какой-либо смысл или объяснить что-либо вам. – abarnert

ответ

-4

Если вы хотите начать/изучать веб-разработки MVC с использованием языка питон я предлагаю начать с Django Framework

+4

Он явно пытается создать графическое приложение для запуска локально, а не веб-приложение. – abarnert

6

ToyMVC «Игрушка MVC (Model View Controller) дизайн» в Tkinter документации, вероятно, что вам «Ищем. Я бы лично разработал вещи по-другому, но в основном это имеет смысл.

Ключ отделяет модель и вид, а контроллер - это все биты, соединяющие модель и представление.

Таким образом, вместо того, чтобы в Application со всем в нем, вы должны были бы эти классы:

  • StoryModel: модель истории.
  • StoryView: Окно или другой виджет, который вы вставляете внутри рамки, хотя в Tk вы можете так же легко сделать его самой рамкой.
  • StoryController: Класс, который с учетом StoryModel и StoryView, сообщит его StoryView, чтобы создать соответствующие виджеты, чтобы отобразить эту историю, и затем будет контролировать как модель, так и вид для изменения и передавать их от одного к другому.

Учитывая, что вы можете создать простой Application, что создает один StoryModel, один StoryView, одно окно фрейма, чтобы поместить вид в, и один StoryController подключить до модели и вид.

Например, StoryModel может выглядеть следующим образом:

class StoryModel(object): 
    body_parts = ['bellybutton', 'big toe', 'medulla oblongato'] 
    def __init__(self): 
     self.person = ObservableStr('') 
     # ... 
     self.is_itchy = ObservableBool(False) 
     # ... 
    def tell(self): 
     story = "The famous explorer " 
     # ... 
     return story 

И тогда вы можете получить фантазии и создать AlternateStoryView, который отображает ту же информацию по-другому, и изменить Application создать один из каждого вида , и контроллер для каждого, прикрепленный к той же модели. Например, вы можете создать представление, которое не использовал сетку, и вместо того, чтобы автоматически заложенные вещи:

class AlternateStoryView(Frame): 
    def __init__(self, master): 
     super(StoryView, self).__init__(master) 
    def add_label(label): 
     label = Label(self, text=label) 
     label.pack() 
     return label 

Если вы знаете о методе trace, вы можете заметить, что Observable не совсем по-другому чем использование Tkinter.StringVar и т. д. Но преимущество (помимо отсутствия неуклюжего синтаксиса trace ...) заключается в том, что нет ничего Tkinter -специально о модели.

Таким образом, вы можете создать GtkStoryView или CursesStoryView, без изменения какого-либо кода в Model и Controller. (Это не работает с ToyMVC, потому что такие вещи, как addButton.config(command=self.addMoney), не будут точно переводить на Gtk + или проклятия, если вы не создали большой эмуляционный слой Tk ... но вам не нужно делать эту ошибку в своем дизайне.)

Также обратите внимание, что использование оберток Observable вокруг всех ваших переменных модели определенно не является единственным способом подключить контроллер или даже обязательно к самому Pythonic.

+1

СПАСИБО !!! ЭТО ДЕЙСТВИТЕЛЬНО ПОМОГАЕТ !!! –

+0

Что такое 'ObservableStr' и' ObservableBool'? Откуда они взялись (код не имеет импорта, и они, конечно, не находятся в 'tkinter')? Это похоже на то, что реализует важный шаблон для синхронизации Tk-to-Model, но я не могу найти его нигде. –

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