ThirdVersion=>MVC design

This commit is contained in:
Yousri 2022-04-19 16:18:57 +02:00
parent 20dc441817
commit f21ccb082d
1 changed files with 118 additions and 112 deletions

View File

@ -2739,7 +2739,6 @@ from tkinter import *
class MainWindow(Frame): class MainWindow(Frame):
def __init__(self): def __init__(self):
Frame.__init__(self,master=None)
Label.__init__(self, text="hello world") Label.__init__(self, text="hello world")
self.pack() self.pack()
@ -2747,7 +2746,7 @@ if __name__ == "__main__":
root = Tk() root = Tk()
root.title("title of the window") root.title("title of the window")
root.geometry("500x300") root.geometry("500x300")
win = MainWindow() MainWindow()
root.mainloop() root.mainloop()
``` ```
@ -2759,7 +2758,6 @@ from tkinter import *
class MainWindow(Frame): class MainWindow(Frame):
def __init__(self): def __init__(self):
Frame.__init__(self,master=None)
Label.__init__(self, text="hello world") Label.__init__(self, text="hello world")
#Label #Label
MyLabel = Label(self, text="This is a label") MyLabel = Label(self, text="This is a label")
@ -2772,7 +2770,7 @@ if __name__ == "__main__":
root = Tk() root = Tk()
root.title("title of the window") root.title("title of the window")
root.geometry("500x300") root.geometry("500x300")
win = MainWindow() MainWindow()
root.mainloop() root.mainloop()
``` ```
@ -2783,7 +2781,6 @@ from tkinter import *
class MainWindow(Frame): class MainWindow(Frame):
def __init__(self): def __init__(self):
Frame.__init__(self,master=None)
Label.__init__(self, text="hello world") Label.__init__(self, text="hello world")
#Label #Label
MyLabel = Label(self, text="This is a label") MyLabel = Label(self, text="This is a label")
@ -2799,7 +2796,7 @@ if __name__ == "__main__":
root = Tk() root = Tk()
root.title("title of the window") root.title("title of the window")
root.geometry("500x300") root.geometry("500x300")
win = MainWindow() MainWindow()
root.mainloop() 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/). 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 ```python
import wx from tkinter import *
class MainWindow(Frame):
class MainWindow(wx.Frame):
def __init__(self): def __init__(self):
wx.Frame.__init__(self, None, title="hello world") Frame.__init__(self, master=None)
self.panel = wx.Panel(self) MyPanel = PanedWindow.__init__(self, bg="Blue")
self.box = wx.BoxSizer() #Label
self.label = wx.StaticText(self.panel, label="this is a label") MyLabel = Label(MyPanel, text="this is a label", bg= "yellow")
self.input = wx.TextCtrl(self.panel) MyLabel.pack(fill="x")
self.button = wx.Button(self.panel, label="I'm clickable!") #Bouton
self.box.Add(self.label) MyButton = Button(MyPanel, text="I'm clickable!")
self.box.Add(self.input) MyButton.place(x=10, y=50)
self.box.Add(self.button) self.pack(fill=BOTH,expand=True)
self.panel.SetSizer(self.box)
self.Show()
if __name__ == "__main__": if __name__ == "__main__":
app = wx.App() root = Tk()
root.title("this is the title of the window")
root.geometry("500x300")
win = MainWindow() win = MainWindow()
app.MainLoop() root.mainloop()
``` ```
This is looking better! This is looking better!
But it requires some explanation though. But it requires some explanation though.
Let's break it down. 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. 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 three different *objects* (`wx.StaticText`, `wx.TextCtrl` and `wx.Button`) each with or without their own settings (such as a label or not). 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).
Next you add these three objects to the `wx.BoxSizer` and you tell the panel to use this box as sizer.
It probably looks a bit convoluted but this is how most GUI libraries work internally. It probably looks a bit convoluted but this is how most GUI libraries work internally.
1. You create a frame 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. 3. You create the visual elements you want and add them one by one to the drawing area.
4. Success 4. Success
Now how do we link **user input** to **code actions**? 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*! 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. 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. Because it is a *method* it has access to *self* so it can modify *anything* within the scope of the instance.
```python ```python
import wx from tkinter import *
import random class MainWindow(Frame):
class MainWindow(wx.Frame):
def __init__(self): def __init__(self):
wx.Frame.__init__(self, None, title="hello world") Frame.__init__(self, master=None)
self.panel = wx.Panel(self) MyPanel = PanedWindow.__init__(self, bg="Blue")
self.box = wx.BoxSizer() #Label
self.label = wx.StaticText(self.panel, label="this is a label") MyLabel = Label(MyPanel, text="this is a label", bg= "yellow")
self.input = wx.TextCtrl(self.panel) MyLabel.pack(fill="x")
self.button = wx.Button(self.panel, label="I'm clickable!") #Bouton
self.button.Bind(wx.EVT_BUTTON, self.set_label_value) MyButton = Button(MyPanel, text="I'm clickable!", command=lambda : self.ButtonEnable(MyLabel))
self.box.Add(self.label) MyButton.place(x=10, y=50)
self.box.Add(self.input) self.pack(fill=BOTH,expand=True)
self.box.Add(self.button)
self.panel.SetSizer(self.box)
self.Show()
def set_label_value(self, event): def ButtonEnable(self, Label):
number = random.randint(0, 100) global number
self.label.SetLabel("{}".format(number)) number += 1
counter = "You have press the button {} time".format(number)
Label.config(text=counter)
number=0
if __name__ == "__main__": if __name__ == "__main__":
app = wx.App() root = Tk()
root.title("this is the title of the window")
root.geometry("500x300")
win = MainWindow() win = MainWindow()
app.MainLoop() root.mainloop()
``` ```
We can use the same *idea* to grab input from the textbox. We can use the same *idea* to grab input from the textbox.
```python ```python
import wx from tkinter import *
class MainWindow(Frame):
class MainWindow(wx.Frame):
def __init__(self): def __init__(self):
wx.Frame.__init__(self, None, title="hello world") Frame.__init__(self, master=None)
self.panel = wx.Panel(self) MyPanel = PanedWindow.__init__(self, bg="Blue")
self.box = wx.BoxSizer() #Label
self.label = wx.StaticText(self.panel, label="this is a label") MyLabel = Label(MyPanel, text="this is a label", bg= "yellow")
self.input = wx.TextCtrl(self.panel) MyLabel.pack(fill="x")
self.button = wx.Button(self.panel, label="I'm clickable!") #TextBox
self.button.Bind(wx.EVT_BUTTON, self.set_label_value) MyEntry = Entry(MyPanel)
self.box.Add(self.label) MyEntry.place(x=200,y=50)
self.box.Add(self.input) #Bouton
self.box.Add(self.button) MyButton = Button(MyPanel, text="I'm clickable!", command=lambda : self.ButtonEnable(MyLabel,MyEntry))
self.panel.SetSizer(self.box) MyButton.place(x=10, y=50)
self.Show() self.pack(fill=BOTH,expand=True)
def set_label_value(self, event):
msg = self.input.GetValue() def ButtonEnable(self, MyLabel, MyEntry):
self.label.SetLabel("{}".format(msg)) MyText = MyEntry.get()
MyLabel.config(text=MyText)
if __name__ == "__main__": if __name__ == "__main__":
app = wx.App() root = Tk()
root.title("this is the title of the window")
root.geometry("500x300")
win = MainWindow() win = MainWindow()
app.MainLoop() root.mainloop()
``` ```
## wxpython guess the number ## Tkinter guess the number
```python ```python
import wx
from tkinter import *
import random import random
class MainWindow(Frame):
class MainWindow(wx.Frame):
def __init__(self): def __init__(self):
wx.Frame.__init__(self, None, title="Guess the number") Frame.__init__(self, master=None, bg="white")
self.number = random.randint(0, 100) MyPanel = PanedWindow.__init__(self)
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()
def set_label_value(self, event): MyNumber = random.randint(0, 100)
result = self.input.GetValue()
if result.isdigit(): #Label
status, context = self.evaluate_user_number(int(result)) MyLabel = Label(MyPanel, text="I have a number in mind...", bg= "blue")
self.label.SetLabel(context) 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: else:
self.label.SetLabel("I need numbers!") MyLabel.config(text="I need numbers!")
def evaluate_user_number(self, number):
if number > self.number: def IsCorrect(self, MyEntry):
return False, "my number is smaller" x = str(MyEntry)
elif number < self.number: if x.isdigit() == True:
return False, "my number is bigger" return True
elif number == self.number: else:
return True, "You win!" return False
if __name__ == "__main__": if __name__ == "__main__":
app = wx.App() root = Tk()
root.title("Guess the number")
root.geometry("500x300")
win = MainWindow() win = MainWindow()
app.MainLoop() root.mainloop()
``` ```
## MVC design pattern ## MVC design pattern
@ -2966,7 +2978,7 @@ A simple console only MVC.
We'll add the GUI view in a bit. We'll add the GUI view in a bit.
```python ```python
import wx from tkinter import *
class ConsoleView(object): class ConsoleView(object):
@ -2986,11 +2998,6 @@ class ConsoleView(object):
"""Prints error messages coming from the controller.""" """Prints error messages coming from the controller."""
print("error: {}".format(msg)) print("error: {}".format(msg))
class WxView(wx.Dialog):
pass
class Model(object): class Model(object):
"""The model houses add data and should implement all methods related to """The model houses add data and should implement all methods related to
adding, modifying and deleting tasks.""" adding, modifying and deleting tasks."""
@ -3053,7 +3060,7 @@ if __name__ == "__main__":
app.run() app.run()
``` ```
And now with the implemented `WxView` class. And now with the implemented `TkinterView` class.
```python ```python
import wx import wx
@ -3110,7 +3117,6 @@ class WxView(wx.Dialog):
called from the controller.""" called from the controller."""
self.task.SetLabel(task) self.task.SetLabel(task)
class Model(object): class Model(object):
"""The model houses add data and should implement all methods related to """The model houses add data and should implement all methods related to
adding, modifying and deleting tasks.""" adding, modifying and deleting tasks."""