From f21ccb082d86d88a116b59780311a8b280b92aed Mon Sep 17 00:00:00 2001 From: Yousri <54667@etu.he2b.be> Date: Tue, 19 Apr 2022 16:18:57 +0200 Subject: [PATCH] ThirdVersion=>MVC design --- learning_python3.md | 230 +++++++++++++++++++++++--------------------- 1 file changed, 118 insertions(+), 112 deletions(-) diff --git a/learning_python3.md b/learning_python3.md index bb08c40..18ed3e9 100644 --- a/learning_python3.md +++ b/learning_python3.md @@ -2739,7 +2739,6 @@ from tkinter import * class MainWindow(Frame): def __init__(self): - Frame.__init__(self,master=None) Label.__init__(self, text="hello world") self.pack() @@ -2747,7 +2746,7 @@ if __name__ == "__main__": root = Tk() root.title("title of the window") root.geometry("500x300") - win = MainWindow() + MainWindow() root.mainloop() ``` @@ -2759,7 +2758,6 @@ from tkinter import * class MainWindow(Frame): def __init__(self): - Frame.__init__(self,master=None) Label.__init__(self, text="hello world") #Label MyLabel = Label(self, text="This is a label") @@ -2772,7 +2770,7 @@ if __name__ == "__main__": root = Tk() root.title("title of the window") root.geometry("500x300") - win = MainWindow() + MainWindow() root.mainloop() ``` @@ -2783,7 +2781,6 @@ from tkinter import * class MainWindow(Frame): def __init__(self): - Frame.__init__(self,master=None) Label.__init__(self, text="hello world") #Label MyLabel = Label(self, text="This is a label") @@ -2799,7 +2796,7 @@ if __name__ == "__main__": root = Tk() root.title("title of the window") root.geometry("500x300") - win = MainWindow() + MainWindow() root.mainloop() ``` @@ -2808,156 +2805,171 @@ We can overcome this problem with parameters of [pack()](https://wxpython.org/Ph We can also use other geometry managers like [grid()](https://www.pythontutorial.net/tkinter/tkinter-grid/) and [place()](https://www.pythontutorial.net/tkinter/tkinter-place/). ```python -import wx +from tkinter import * - -class MainWindow(wx.Frame): +class MainWindow(Frame): def __init__(self): - wx.Frame.__init__(self, None, title="hello world") - self.panel = wx.Panel(self) - self.box = wx.BoxSizer() - self.label = wx.StaticText(self.panel, label="this is a label") - self.input = wx.TextCtrl(self.panel) - self.button = wx.Button(self.panel, label="I'm clickable!") - self.box.Add(self.label) - self.box.Add(self.input) - self.box.Add(self.button) - self.panel.SetSizer(self.box) - self.Show() - + Frame.__init__(self, master=None) + MyPanel = PanedWindow.__init__(self, bg="Blue") + #Label + MyLabel = Label(MyPanel, text="this is a label", bg= "yellow") + MyLabel.pack(fill="x") + #Bouton + MyButton = Button(MyPanel, text="I'm clickable!") + MyButton.place(x=10, y=50) + self.pack(fill=BOTH,expand=True) if __name__ == "__main__": - app = wx.App() + root = Tk() + root.title("this is the title of the window") + root.geometry("500x300") win = MainWindow() - app.MainLoop() + root.mainloop() ``` This is looking better! But it requires some explanation though. Let's break it down. -The `wx.Frame` is your **window** in which you create a `wx.Panel` which is used to draw thing to. -To this panel you're adding three different *objects* (`wx.StaticText`, `wx.TextCtrl` and `wx.Button`) each with or without their own settings (such as a label or not). -Next you add these three objects to the `wx.BoxSizer` and you tell the panel to use this box as sizer. +The `Frame.__init__` is your **window** in which you create a `PanedWindow.__init__` which is used to draw thing to. +To this panel you're adding two different *objects* (`Label()` and `Button()`) each with or without their own settings (such as a label or not). It probably looks a bit convoluted but this is how most GUI libraries work internally. 1. You create a frame -2. Within this frame you create a *drawing area* and set some form of automatic layout to it (the `wx.BoxSizer`). +2. Within this frame you create a *drawing area* and set some form of automatic layout to it. 3. You create the visual elements you want and add them one by one to the drawing area. 4. Success Now how do we link **user input** to **code actions**? This is a complicated way of saying *actually do something when I click the damn button*! -For this we'll need to create a function, or better yet a method to the `wx.Frame` objects. +For this we'll need to create a function, or better yet a method to the `Frame.__init__` objects. Each time we click the button, that method will be called. Because it is a *method* it has access to *self* so it can modify *anything* within the scope of the instance. ```python -import wx -import random +from tkinter import * +class MainWindow(Frame): + def __init__(self): + Frame.__init__(self, master=None) + MyPanel = PanedWindow.__init__(self, bg="Blue") + #Label + MyLabel = Label(MyPanel, text="this is a label", bg= "yellow") + MyLabel.pack(fill="x") + #Bouton + MyButton = Button(MyPanel, text="I'm clickable!", command=lambda : self.ButtonEnable(MyLabel)) + MyButton.place(x=10, y=50) + self.pack(fill=BOTH,expand=True) + + def ButtonEnable(self, Label): + global number + number += 1 + counter = "You have press the button {} time".format(number) + Label.config(text=counter) -class MainWindow(wx.Frame): - def __init__(self): - wx.Frame.__init__(self, None, title="hello world") - self.panel = wx.Panel(self) - self.box = wx.BoxSizer() - self.label = wx.StaticText(self.panel, label="this is a label") - self.input = wx.TextCtrl(self.panel) - self.button = wx.Button(self.panel, label="I'm clickable!") - self.button.Bind(wx.EVT_BUTTON, self.set_label_value) - self.box.Add(self.label) - self.box.Add(self.input) - self.box.Add(self.button) - self.panel.SetSizer(self.box) - self.Show() - - def set_label_value(self, event): - number = random.randint(0, 100) - self.label.SetLabel("{}".format(number)) - +number=0 if __name__ == "__main__": - app = wx.App() + root = Tk() + root.title("this is the title of the window") + root.geometry("500x300") win = MainWindow() - app.MainLoop() + root.mainloop() + + ``` We can use the same *idea* to grab input from the textbox. ```python -import wx +from tkinter import * + +class MainWindow(Frame): + def __init__(self): + Frame.__init__(self, master=None) + MyPanel = PanedWindow.__init__(self, bg="Blue") + #Label + MyLabel = Label(MyPanel, text="this is a label", bg= "yellow") + MyLabel.pack(fill="x") + #TextBox + MyEntry = Entry(MyPanel) + MyEntry.place(x=200,y=50) + #Bouton + MyButton = Button(MyPanel, text="I'm clickable!", command=lambda : self.ButtonEnable(MyLabel,MyEntry)) + MyButton.place(x=10, y=50) + self.pack(fill=BOTH,expand=True) -class MainWindow(wx.Frame): - def __init__(self): - wx.Frame.__init__(self, None, title="hello world") - self.panel = wx.Panel(self) - self.box = wx.BoxSizer() - self.label = wx.StaticText(self.panel, label="this is a label") - self.input = wx.TextCtrl(self.panel) - self.button = wx.Button(self.panel, label="I'm clickable!") - self.button.Bind(wx.EVT_BUTTON, self.set_label_value) - self.box.Add(self.label) - self.box.Add(self.input) - self.box.Add(self.button) - self.panel.SetSizer(self.box) - self.Show() - - def set_label_value(self, event): - msg = self.input.GetValue() - self.label.SetLabel("{}".format(msg)) + def ButtonEnable(self, MyLabel, MyEntry): + MyText = MyEntry.get() + MyLabel.config(text=MyText) if __name__ == "__main__": - app = wx.App() + root = Tk() + root.title("this is the title of the window") + root.geometry("500x300") win = MainWindow() - app.MainLoop() + root.mainloop() + + ``` -## wxpython guess the number +## Tkinter guess the number ```python -import wx + +from tkinter import * import random +class MainWindow(Frame): + def __init__(self): + Frame.__init__(self, master=None, bg="white") + MyPanel = PanedWindow.__init__(self) -class MainWindow(wx.Frame): - def __init__(self): - wx.Frame.__init__(self, None, title="Guess the number") - self.number = random.randint(0, 100) - self.panel = wx.Panel(self) - self.box = wx.BoxSizer(wx.VERTICAL) - self.label = wx.StaticText(self.panel, label="I have a number in mind...") - self.input = wx.TextCtrl(self.panel) - self.button = wx.Button(self.panel, label="I'm clickable!") - self.button.Bind(wx.EVT_BUTTON, self.set_label_value) - self.box.Add(self.label) - self.box.Add(self.input) - self.box.Add(self.button) - self.panel.SetSizer(self.box) - self.Show() + MyNumber = random.randint(0, 100) - def set_label_value(self, event): - result = self.input.GetValue() - if result.isdigit(): - status, context = self.evaluate_user_number(int(result)) - self.label.SetLabel(context) + #Label + MyLabel = Label(MyPanel, text="I have a number in mind...", bg= "blue") + MyLabel.pack(fill="x", ipadx=25, ipady=20) + #TextBox + MyEntry = Entry(MyPanel) + MyEntry.place(x=200,y=90) + #Bouton + MyButton = Button(MyPanel, text="I'm clickable!", command=lambda : self.ButtonEnable(MyLabel,MyEntry, MyNumber)) + MyButton.place(x=10, y=90) + + self.pack(fill=BOTH,expand=True) + + + def ButtonEnable(self, MyLabel, MyEntry, MyNumber): + if self.IsCorrect(MyEntry.get()): + number = int(MyEntry.get()) + if number > MyNumber: + MyLabel.config(text="My number is smaller") + elif number < MyNumber: + MyLabel.config(text="My number is bigger") + else: + MyLabel.cionfig(text="You WIN!") else: - self.label.SetLabel("I need numbers!") + MyLabel.config(text="I need numbers!") - def evaluate_user_number(self, number): - if number > self.number: - return False, "my number is smaller" - elif number < self.number: - return False, "my number is bigger" - elif number == self.number: - return True, "You win!" + + def IsCorrect(self, MyEntry): + x = str(MyEntry) + if x.isdigit() == True: + return True + else: + return False if __name__ == "__main__": - app = wx.App() + root = Tk() + root.title("Guess the number") + root.geometry("500x300") win = MainWindow() - app.MainLoop() + root.mainloop() + + ``` ## MVC design pattern @@ -2966,7 +2978,7 @@ A simple console only MVC. We'll add the GUI view in a bit. ```python -import wx +from tkinter import * class ConsoleView(object): @@ -2986,11 +2998,6 @@ class ConsoleView(object): """Prints error messages coming from the controller.""" print("error: {}".format(msg)) - -class WxView(wx.Dialog): - pass - - class Model(object): """The model houses add data and should implement all methods related to adding, modifying and deleting tasks.""" @@ -3053,7 +3060,7 @@ if __name__ == "__main__": app.run() ``` -And now with the implemented `WxView` class. +And now with the implemented `TkinterView` class. ```python import wx @@ -3110,7 +3117,6 @@ class WxView(wx.Dialog): called from the controller.""" self.task.SetLabel(task) - class Model(object): """The model houses add data and should implement all methods related to adding, modifying and deleting tasks."""