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):
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."""