tkinter review
This commit is contained in:
		
							parent
							
								
									382d0db2b9
								
							
						
					
					
						commit
						dabb20053a
					
				| 
						 | 
					@ -3,134 +3,134 @@
 | 
				
			||||||
## Tkinter helloworld
 | 
					## Tkinter helloworld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The absolute most basic way to have a *hello world* GUI program up and running with Tkinter is the following.
 | 
					The absolute most basic way to have a *hello world* GUI program up and running with Tkinter is the following.
 | 
				
			||||||
 | 
					It creates an *application*, sets the *title* as `hello world` and enters the **main eventloop**.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```python
 | 
					```python
 | 
				
			||||||
from tkinter import *
 | 
					import tkinter as tk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
root = Tk()
 | 
					root = tk.Tk()
 | 
				
			||||||
 | 
					root.title("hello world")
 | 
				
			||||||
MyLabel = Label(root,text="hello world")
 | 
					 | 
				
			||||||
MyLabel.pack()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
root.mainloop()
 | 
					root.mainloop()
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
Tkinter have two popular architectures, the Tcl and Tk. This two architectures are different, they have their own functionality and their own official documentation. 
 | 
					 | 
				
			||||||
We are gonna use the Tk architecture.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
The Tk architecture is used to create a GUI widget. He adds a lot of custom commands, so the widget is very customizable. 
 | 
					Tkinter has two popular architectures, Tcl and Tk.
 | 
				
			||||||
 | 
					These two architectures are quite different as they each have their own functionality and their own official documentation. 
 | 
				
			||||||
 | 
					We are going use the Tk architecture.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
In the previous code,the `mainloop()` instruction allows us to open the main window and to not close immediately the window.
 | 
					The Tk architecture is used to create a GUI widget which has a lot of **methods** and **attributes** so it's quite customizable.
 | 
				
			||||||
And then, the `Label()` method creates label in a layout. This method has many parameters to customize a label. The instruction `pack()` will be always call , this instruction can 
 | 
					
 | 
				
			||||||
add and adjust a widget. 
 | 
					In the previous code,the `mainloop()` method allows us to open the main window and to not close the window immediately .
 | 
				
			||||||
 | 
					This **event loop** will process all mouse event, button clicks, and changes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
While it works we know better by now.
 | 
					While it works we know better by now.
 | 
				
			||||||
We should include the `if __name__ == "__main__"` statement.
 | 
					We should include the `if __name__ == "__main__"` statement so let's do this!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```python
 | 
					```python
 | 
				
			||||||
from tkinter import *
 | 
					import tkinter as tk
 | 
				
			||||||
if __name__ == "__main__":
 | 
					 | 
				
			||||||
    root = Tk()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MyLabel = Label(root,text="hello world")
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    MyLabel.pack()
 | 
					    root = tk.Tk()
 | 
				
			||||||
 | 
					    root.title("hello world")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    root.mainloop()
 | 
					    root.mainloop()
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The instance of `Tk()` is what will actually process our event loop and the `root` is the content of our window. We can customize `root` with instruction like geometry, title,etc.
 | 
					The instance of `tk.Tk()` is what will actually process our event loop and the `root` is the content of our window. We can customize `root` with instruction like geometry, title, etc.
 | 
				
			||||||
In the latter we will create our button and labels so should create our own class and inherit from it.
 | 
					To this instance we can attach other widgets and display them.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```python
 | 
					```python
 | 
				
			||||||
from tkinter import *
 | 
					import tkinter as tk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MainWindow(Frame):
 | 
					
 | 
				
			||||||
 | 
					class Application(tk.Tk):
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        Label.__init__(self, text="hello world")
 | 
					        tk.Tk.__init__(self)
 | 
				
			||||||
        self.pack()
 | 
					        self.title("hello world")
 | 
				
			||||||
 | 
					        self.geometry("500x400")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    root = Tk()
 | 
					    app = Application()
 | 
				
			||||||
    root.title("title of the window") 
 | 
					    app.mainloop()
 | 
				
			||||||
    root.geometry("500x300")
 | 
					 | 
				
			||||||
    MainWindow()
 | 
					 | 
				
			||||||
    root.mainloop()
 | 
					 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
We can add content to the *frame*, such as labels, input boxes and buttons as follows.
 | 
					We can add content to this window, such as labels, input boxes and buttons as follows.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```python
 | 
					```python
 | 
				
			||||||
from tkinter import *
 | 
					import tkinter as tk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MainWindow(Frame):
 | 
					
 | 
				
			||||||
 | 
					class Application(tk.Tk):
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        Label.__init__(self, text="hello world")
 | 
					        tk.Tk.__init__(self)
 | 
				
			||||||
        #Label
 | 
					        self.title("hello world")
 | 
				
			||||||
        MyLabel = Label(self, text="This is a label")
 | 
					        self.geometry("500x400")
 | 
				
			||||||
        MyLabel.pack()
 | 
					        self.resizable(0, 0)
 | 
				
			||||||
 | 
					        self.label = tk.Label(self, text="This is a label", bg="yellow")
 | 
				
			||||||
 | 
					        self.label.pack()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.config(bg="yellow")
 | 
					 | 
				
			||||||
        self.pack()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    root = Tk()
 | 
					    app = Application()
 | 
				
			||||||
    root.title("title of the window")
 | 
					    app.mainloop()
 | 
				
			||||||
    root.geometry("500x300")
 | 
					 | 
				
			||||||
    MainWindow()
 | 
					 | 
				
			||||||
    root.mainloop()
 | 
					 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Let's try to put multiple visual object into the same frame.
 | 
					Let's try to put multiple visual object into the same window.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```python3
 | 
					```python3
 | 
				
			||||||
from tkinter import *
 | 
					import tkinter as tk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MainWindow(Frame):
 | 
					
 | 
				
			||||||
 | 
					class Application(tk.Tk):
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        Label.__init__(self, text="hello world")
 | 
					        tk.Tk.__init__(self)
 | 
				
			||||||
        #Label
 | 
					        self.title("hello world")
 | 
				
			||||||
        MyLabel = Label(self, text="This is a label")
 | 
					        self.geometry("500x400")
 | 
				
			||||||
        MyLabel.pack()
 | 
					        self.label = tk.Label(text="This is a label")
 | 
				
			||||||
        #Button
 | 
					        self.label.pack()
 | 
				
			||||||
        MyButton = Button(self, text="I'm clickable!")
 | 
					
 | 
				
			||||||
        MyButton.pack()
 | 
					        self.button = tk.Button(text="I'm clickable!")
 | 
				
			||||||
 | 
					        self.button.pack()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.output = tk.Label(text="I'm a second label")
 | 
				
			||||||
 | 
					        self.output.pack()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.config(bg="yellow")
 | 
					 | 
				
			||||||
        self.pack()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    root = Tk()
 | 
					    app = Application()
 | 
				
			||||||
    root.title("title of the window")
 | 
					    app.mainloop()
 | 
				
			||||||
    root.geometry("500x300")
 | 
					 | 
				
			||||||
    MainWindow()
 | 
					 | 
				
			||||||
    root.mainloop()
 | 
					 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You see how they are *stacked* one on top of the other?
 | 
					You see how they are *stacked* one on top of the other?
 | 
				
			||||||
We can overcome this problem with parameters of [pack()](https://wxpython.org/Phoenix/docs/html/sizers_overview.html). 
 | 
					We can overcome this problem with parameters of [pack()](https://wxpython.org/Phoenix/docs/html/sizers_overview.html) or we can 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
 | 
				
			||||||
from tkinter import *
 | 
					import tkinter as tk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MainWindow(Frame):
 | 
					
 | 
				
			||||||
 | 
					class Application(tk.Tk):
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        Frame.__init__(self, master=None)
 | 
					        tk.Tk.__init__(self)
 | 
				
			||||||
        MyPanel = PanedWindow.__init__(self, bg="Blue")
 | 
					        self.title("hello world")
 | 
				
			||||||
        #Label
 | 
					        self.geometry("500x400")
 | 
				
			||||||
        MyLabel = Label(MyPanel, text="this is a label", bg= "yellow")
 | 
					        self.resizable(0, 0)
 | 
				
			||||||
        MyLabel.pack(fill="x")
 | 
					        self.label = tk.Label(self, text="This is a label", bg="yellow")
 | 
				
			||||||
        #Bouton
 | 
					        self.label.grid(column=0, row=0, sticky=tk.W, padx=5, pady=5)
 | 
				
			||||||
        MyButton = Button(MyPanel, text="I'm clickable!")
 | 
					
 | 
				
			||||||
        MyButton.place(x=10, y=50)
 | 
					        self.button = tk.Button(self, text="I'm clickable!")
 | 
				
			||||||
        self.pack(fill=BOTH,expand=True)
 | 
					        self.button.grid(column=1, row=0, sticky=tk.E, padx=5, pady=5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.output = tk.Label(self, text="I'm a second label")
 | 
				
			||||||
 | 
					        self.output.grid(column=1, row=1, sticky=tk.E, padx=5, pady=5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.config(bg="yellow")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    root = Tk()
 | 
					    app = Application()
 | 
				
			||||||
    root.title("this is the title of the window") 
 | 
					    app.mainloop()
 | 
				
			||||||
    root.geometry("500x300") 
 | 
					 | 
				
			||||||
    win = MainWindow()
 | 
					 | 
				
			||||||
    root.mainloop()
 | 
					 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This is looking better!
 | 
					This is looking better!
 | 
				
			||||||
| 
						 | 
					@ -152,137 +152,179 @@ 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
 | 
				
			||||||
from tkinter import *
 | 
					import tkinter as tk
 | 
				
			||||||
class MainWindow(Frame):
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Application(tk.Tk):
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        Frame.__init__(self, master=None)
 | 
					        tk.Tk.__init__(self)
 | 
				
			||||||
        MyPanel = PanedWindow.__init__(self, bg="Blue")
 | 
					        self.title("hello world")
 | 
				
			||||||
        #Label
 | 
					        self.geometry("500x400")
 | 
				
			||||||
        MyLabel = Label(MyPanel, text="this is a label", bg= "yellow")
 | 
					        self.resizable(0, 0)
 | 
				
			||||||
        MyLabel.pack(fill="x")
 | 
					        self.label = tk.Label(self, text="This is a label", bg="yellow")
 | 
				
			||||||
        #Bouton
 | 
					        self.label.pack()
 | 
				
			||||||
        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):
 | 
					        self.button = tk.Button(self, text="I'm clickable!", command=self.clicked)
 | 
				
			||||||
        global number
 | 
					        self.button.pack()
 | 
				
			||||||
        number += 1
 | 
					 | 
				
			||||||
        counter = "You have press the button {} time".format(number)
 | 
					 | 
				
			||||||
        Label.config(text=counter)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.output = tk.Label(self, text="I'm a second label")
 | 
				
			||||||
 | 
					        self.output.pack()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
number=0
 | 
					        self.config(bg="yellow")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					    def clicked(self):
 | 
				
			||||||
    root = Tk()
 | 
					        print("hello world!")
 | 
				
			||||||
    root.title("this is the title of the window") 
 | 
					 | 
				
			||||||
    root.geometry("500x300") 
 | 
					 | 
				
			||||||
    win = MainWindow()
 | 
					 | 
				
			||||||
    root.mainloop()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
We can use the same *idea* to grab input from the textbox.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```python
 | 
					 | 
				
			||||||
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) 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def ButtonEnable(self, MyLabel, MyEntry):
 | 
					 | 
				
			||||||
        MyText = MyEntry.get()
 | 
					 | 
				
			||||||
        MyLabel.config(text=MyText)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    root = Tk()
 | 
					    app = Application()
 | 
				
			||||||
    root.title("this is the title of the window")
 | 
					    app.mainloop()
 | 
				
			||||||
    root.geometry("500x300") 
 | 
					 | 
				
			||||||
    win = MainWindow()
 | 
					 | 
				
			||||||
    root.mainloop()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Tkinter guess the number
 | 
					We can see *hello world!* printed to the console with each click!
 | 
				
			||||||
 | 
					As we're using a `class` we have *access* to the instance of the application so we can use the `self.output` label to show our messages.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```python
 | 
					```python
 | 
				
			||||||
import time
 | 
					import tkinter as tk
 | 
				
			||||||
from tkinter import *
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Application(tk.Tk):
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        tk.Tk.__init__(self)
 | 
				
			||||||
 | 
					        self.title("hello world")
 | 
				
			||||||
 | 
					        self.geometry("500x400")
 | 
				
			||||||
 | 
					        self.resizable(0, 0)
 | 
				
			||||||
 | 
					        self.label = tk.Label(self, text="This is a label", bg="yellow")
 | 
				
			||||||
 | 
					        self.label.pack()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.button = tk.Button(self, text="I'm clickable!", command=self.clicked)
 | 
				
			||||||
 | 
					        self.button.pack()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.output = tk.Label(self, text="I'm a second label")
 | 
				
			||||||
 | 
					        self.output.pack()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.config(bg="yellow")
 | 
				
			||||||
 | 
					        self.counter = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clicked(self):
 | 
				
			||||||
 | 
					        self.counter += 1
 | 
				
			||||||
 | 
					        self.output.config(text="butter has been clicked {} times".format(self.counter))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    app = Application()
 | 
				
			||||||
 | 
					    app.mainloop()
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					🏃 Try it
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We can use the same *idea* to grab input from the input boxes called `tk.Entry`.
 | 
				
			||||||
 | 
					The code below *adds* two numbers but it's not working properly.
 | 
				
			||||||
 | 
					Can you fix it for me please?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```python
 | 
				
			||||||
 | 
					import tkinter as tk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Application(tk.Tk):
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        tk.Tk.__init__(self)
 | 
				
			||||||
 | 
					        self.title("hello world")
 | 
				
			||||||
 | 
					        self.geometry("500x400")
 | 
				
			||||||
 | 
					        self.resizable(0, 0)
 | 
				
			||||||
 | 
					        self.label_one = tk.Label(self, text="Number 1:", bg="yellow")
 | 
				
			||||||
 | 
					        self.label_one.grid(column=0, row=0, sticky=tk.W, padx=5, pady=5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.label_two = tk.Label(self, text="Number 2:", bg="yellow")
 | 
				
			||||||
 | 
					        self.label_two.grid(column=0, row=1, sticky=tk.W, padx=5, pady=5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.input_one = tk.Entry(self)
 | 
				
			||||||
 | 
					        self.input_one.grid(column=1, row=0, sticky=tk.W, padx=5, pady=5)
 | 
				
			||||||
 | 
					        self.input_two = tk.Entry(self)
 | 
				
			||||||
 | 
					        self.input_two.grid(column=1, row=1, sticky=tk.W, padx=5, pady=5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.button = tk.Button(self, text="add two numbers", command=self.clicked)
 | 
				
			||||||
 | 
					        self.button.grid(column=0, row=3, sticky=tk.W, padx=5, pady=5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.output = tk.Label(self, text="...")
 | 
				
			||||||
 | 
					        self.output.grid(column=1, row=3, sticky=tk.W, padx=5, pady=5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.config(bg="yellow")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clicked(self):
 | 
				
			||||||
 | 
					        number_one = self.input_one.get()
 | 
				
			||||||
 | 
					        number_two = self.input_two.get()
 | 
				
			||||||
 | 
					        total = number_one + number_two
 | 
				
			||||||
 | 
					        self.output.config(text="sum: {}".format(total))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    app = Application()
 | 
				
			||||||
 | 
					    app.mainloop()
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Coding challenge - Guess the number
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Can you code me a *guess the number* game but using `tkinter`?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<details>
 | 
				
			||||||
 | 
					<summary>Spoiler warning</summary>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```python
 | 
				
			||||||
 | 
					import tkinter as tk
 | 
				
			||||||
import random
 | 
					import random
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MainWindow(Frame):
 | 
					
 | 
				
			||||||
 | 
					class Application(tk.Tk):
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        Frame.__init__(self, master=None, bg="white")
 | 
					        tk.Tk.__init__(self)
 | 
				
			||||||
        MyPanel = PanedWindow.__init__(self)
 | 
					        self.title("hello world")
 | 
				
			||||||
 | 
					        self.geometry("500x400")
 | 
				
			||||||
 | 
					        self.resizable(0, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MyNumber = random.randint(0, 100)
 | 
					        self.number = random.randint(0, 10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #Label
 | 
					        self.header = tk.Label(text="I have a number in mind...")
 | 
				
			||||||
        self.MyLabel = Label(MyPanel, text="I have a number in mind...", bg= "blue")
 | 
					        self.header.grid(column=0, row=0, sticky=tk.W)
 | 
				
			||||||
        self.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(MyEntry, MyNumber))
 | 
					 | 
				
			||||||
        MyButton.place(x=10, y=90)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.pack(fill=BOTH,expand=True)
 | 
					        self.question = tk.Label(self, text="What's your guess?")
 | 
				
			||||||
 | 
					        self.question.grid(column=0, row=1, sticky=tk.W)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.input = tk.Entry(self)
 | 
				
			||||||
 | 
					        self.input.grid(column=1, row=1, sticky=tk.W)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def ButtonEnable(self, MyEntry, MyNumber):
 | 
					        self.button = tk.Button(self, text="check", command=self.clicked)
 | 
				
			||||||
        if self.IsCorrect(MyEntry.get()):
 | 
					        self.button.grid(column=0, row=2, sticky=tk.W)
 | 
				
			||||||
            number = int(MyEntry.get())
 | 
					
 | 
				
			||||||
            if number != MyNumber:
 | 
					        self.output = tk.Label(self, text="...")
 | 
				
			||||||
                self.GameOver(number, MyNumber)
 | 
					        self.output.grid(column=1, row=2, sticky=tk.W)
 | 
				
			||||||
            else:
 | 
					    
 | 
				
			||||||
                self.Win()
 | 
					    def _is_entry_digit(self):
 | 
				
			||||||
 | 
					        number = self.input.get()
 | 
				
			||||||
 | 
					        if number.isdigit():
 | 
				
			||||||
 | 
					            number = int(number)
 | 
				
			||||||
 | 
					            return number
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clicked(self):
 | 
				
			||||||
 | 
					        number = self._is_entry_digit()
 | 
				
			||||||
 | 
					        if not number:
 | 
				
			||||||
 | 
					            msg = "numbers please..."
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.MyLabel.config(text="I need numbers!")
 | 
					            if number < self.number:
 | 
				
			||||||
 | 
					                msg = "my number is bigger"
 | 
				
			||||||
    def GameOver(self, number, MyNumber):
 | 
					            elif number > self.number:
 | 
				
			||||||
        if number > MyNumber:
 | 
					                msg = "my number is smaller"
 | 
				
			||||||
            self.MyLabel.config(text="My number is smaller")
 | 
					            elif number == self.number:
 | 
				
			||||||
        else:
 | 
					                msg = "bingo!"
 | 
				
			||||||
            self.MyLabel.config(text="My number is bigger")
 | 
					        self.output.config(text=msg)
 | 
				
			||||||
 | 
					 | 
				
			||||||
    def Win(self):
 | 
					 | 
				
			||||||
        self.MyLabel.config(text="You WIN!")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def IsCorrect(self, MyEntry):
 | 
					 | 
				
			||||||
        x = str(MyEntry)
 | 
					 | 
				
			||||||
        if x.isdigit() == True:
 | 
					 | 
				
			||||||
            return True
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            return False
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    root = Tk()
 | 
					    app = Application()
 | 
				
			||||||
    root.title("Guess the number")
 | 
					    app.mainloop()
 | 
				
			||||||
    root.geometry("500x300")
 | 
					 | 
				
			||||||
    win = MainWindow()
 | 
					 | 
				
			||||||
    root.mainloop()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					</details>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## MVC design pattern
 | 
					## MVC design pattern
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -290,215 +332,152 @@ 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
 | 
				
			||||||
from tkinter import *
 | 
					import tkinter as tk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ConsoleView(object):
 | 
					class ConsoleView(object):
 | 
				
			||||||
    """A view for console."""
 | 
					    """A view for console."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def select_task(self):
 | 
					    def __init__(self, controller):
 | 
				
			||||||
        """Asks which index to look up."""
 | 
					 | 
				
			||||||
        idx = input("which task do you want to see? ")
 | 
					 | 
				
			||||||
        return idx
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def show(self, task):
 | 
					 | 
				
			||||||
        """Displays the task to the console. This method is called from the
 | 
					 | 
				
			||||||
        controller."""
 | 
					 | 
				
			||||||
        print("your task: {}".format(task))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def error(self, msg):
 | 
					 | 
				
			||||||
        """Prints error messages coming from the controller."""
 | 
					 | 
				
			||||||
        print("error: {}".format(msg))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Model(object):
 | 
					 | 
				
			||||||
    """The model houses add data and should implement all methods related to
 | 
					 | 
				
			||||||
    adding, modifying and deleting tasks."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = ["go to the shops", "dryhop beer", "drop of motorbike"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_task(self, idx):
 | 
					 | 
				
			||||||
        """Performs a task lookun into the database and returns it when found.
 | 
					 | 
				
			||||||
        If no task is found, it returns an error message that will be displayed
 | 
					 | 
				
			||||||
        in the view (via the controller)."""
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            task = Model.db[idx]
 | 
					 | 
				
			||||||
        except IndexError:
 | 
					 | 
				
			||||||
            task = "task with {} not found!".format(idx)
 | 
					 | 
				
			||||||
        return task
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Controller(object):
 | 
					 | 
				
			||||||
    """Binds the model and the view together."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, view):
 | 
					 | 
				
			||||||
        self.model = Model()
 | 
					 | 
				
			||||||
        self.view = view 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def run(self):
 | 
					 | 
				
			||||||
        """The controller's main function. Depending on what type of view is 
 | 
					 | 
				
			||||||
        selected, a different event loop is setup. Do note that the ConsoleView
 | 
					 | 
				
			||||||
        is not a real event loop, just a basic flow of action."""
 | 
					 | 
				
			||||||
        if self.view is ConsoleView:
 | 
					 | 
				
			||||||
            self.view = self.view()
 | 
					 | 
				
			||||||
            self._run_console_view()
 | 
					 | 
				
			||||||
        elif self.view is TkinterView:
 | 
					 | 
				
			||||||
            root = Tk()
 | 
					 | 
				
			||||||
            root.title("Task Manager")
 | 
					 | 
				
			||||||
            root.geometry("500x300")
 | 
					 | 
				
			||||||
            self.view = self.view()
 | 
					 | 
				
			||||||
            self.view._set_controller(self)
 | 
					 | 
				
			||||||
            root.mainloop()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_task_from_model(self, idx):
 | 
					 | 
				
			||||||
        """Needed for the TkinterView to communicate with the controller."""
 | 
					 | 
				
			||||||
        task = self.model.get_task(idx)
 | 
					 | 
				
			||||||
        self.view.show_task(task)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _run_console_view(self):
 | 
					 | 
				
			||||||
        """Super simple event loop."""
 | 
					 | 
				
			||||||
        while True:
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                idx = self.view.select_task()
 | 
					 | 
				
			||||||
                idx = int(idx)
 | 
					 | 
				
			||||||
            except Exception as e:
 | 
					 | 
				
			||||||
                self.view.error(e)
 | 
					 | 
				
			||||||
                continue
 | 
					 | 
				
			||||||
            task = self.model.get_task(idx)
 | 
					 | 
				
			||||||
            self.view.show(task)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if __name__ == "__main__":
 | 
					 | 
				
			||||||
    view = ConsoleView
 | 
					 | 
				
			||||||
    app = Controller(view)
 | 
					 | 
				
			||||||
    app.run()
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
And now with the implemented `TkinterView` class.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```python
 | 
					 | 
				
			||||||
from tkinter import *
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ConsoleView(object):
 | 
					 | 
				
			||||||
    """A view for console."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def select_task(self):
 | 
					 | 
				
			||||||
        """Asks which index to look up."""
 | 
					 | 
				
			||||||
        idx = input("which task do you want to see? ")
 | 
					 | 
				
			||||||
        return idx
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def show(self, task):
 | 
					 | 
				
			||||||
        """Displays the task to the console. This method is called from the
 | 
					 | 
				
			||||||
        controller."""
 | 
					 | 
				
			||||||
        print("your task: {}".format(task))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def error(self, msg):
 | 
					 | 
				
			||||||
        """Prints error messages coming from the controller."""
 | 
					 | 
				
			||||||
        print("error: {}".format(msg))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class TkinterView(Frame):
 | 
					 | 
				
			||||||
    """A view using a wx.Dialog window"""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        Frame.__init__(self, master=None)
 | 
					 | 
				
			||||||
        #Panel
 | 
					 | 
				
			||||||
        self.panel = PanedWindow(self, bg="green")
 | 
					 | 
				
			||||||
        self.panel.pack(fill=BOTH, expand=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #Task Label
 | 
					 | 
				
			||||||
        self.task = Label(self.panel, text="your task")
 | 
					 | 
				
			||||||
        self.task.pack(expand=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #SpinBox
 | 
					 | 
				
			||||||
        self.idx = Spinbox(self.panel, from_=0, to=2, wrap=True )
 | 
					 | 
				
			||||||
        self.idx.pack(side= TOP)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #Button
 | 
					 | 
				
			||||||
        self.button = Button(self.panel, text="submit", command=lambda : self.select_task())
 | 
					 | 
				
			||||||
        self.button.pack(ipadx=60, ipady=30)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.pack(fill=BOTH, expand=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _set_controller(self, controller):
 | 
					 | 
				
			||||||
        """Set the controller so the view can communicate it's requests to it
 | 
					 | 
				
			||||||
        and update it's values too."""
 | 
					 | 
				
			||||||
        self.controller = controller
 | 
					        self.controller = controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def select_task(self):
 | 
					    def select_task(self):
 | 
				
			||||||
        """Gets the index to look up in the model and submits the request to
 | 
					        """Asks which index to look up."""
 | 
				
			||||||
        the controller."""
 | 
					        idx = input("which task do you want to see? ")
 | 
				
			||||||
        idx = self.idx.get()
 | 
					        return idx
 | 
				
			||||||
        self.controller.get_task_from_model(idx)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def show_task(self, task):
 | 
					    def show_message(self, msg):
 | 
				
			||||||
        """Updates the visual label in the view with the task. This method is
 | 
					        print("MSG: {}".format(msg))
 | 
				
			||||||
        called from the controller."""
 | 
					
 | 
				
			||||||
        self.task.config(text=task)
 | 
					    def show(self, task):
 | 
				
			||||||
 | 
					        """Displays the task to the console. This method is called from the
 | 
				
			||||||
 | 
					        controller."""
 | 
				
			||||||
 | 
					        print("your task: {}".format(task))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def error(self, msg):
 | 
				
			||||||
 | 
					        """Prints error messages coming from the controller."""
 | 
				
			||||||
 | 
					        print("error: {}".format(msg))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def mainloop(self):
 | 
				
			||||||
 | 
					        """Super simple event loop."""
 | 
				
			||||||
 | 
					        while True:
 | 
				
			||||||
 | 
					            self.controller.request_number_of_tasks_from_model()
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                idx = self.select_task()
 | 
				
			||||||
 | 
					                idx = int(idx)
 | 
				
			||||||
 | 
					            except Exception as e:
 | 
				
			||||||
 | 
					                self.error(e)
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            self.controller.request_task_from_model(idx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    db = ["go to the shops", "dryhop beer", "drop of motorbike"]
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        self.db = ["go to the shops", "dryhop beer", "drop of motorbike"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __len__(self):
 | 
				
			||||||
 | 
					        return len(self.db)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_task(self, idx):
 | 
					    def get_task(self, idx):
 | 
				
			||||||
        """Performs a task lookun into the database and returns it when found.
 | 
					        """Performs a task lookun into the database and returns it when found.
 | 
				
			||||||
        If no task is found, it returns an error message that will be displayed
 | 
					        If no task is found, it returns an error message that will be displayed
 | 
				
			||||||
        in the view (via the controller)."""
 | 
					        in the view (via the controller)."""
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            task = Model.db[int(idx)]
 | 
					            task = self.db[idx]
 | 
				
			||||||
        except IndexError:
 | 
					        except IndexError:
 | 
				
			||||||
            task = "task with {} not found!".format(idx)
 | 
					            task = None
 | 
				
			||||||
        return task
 | 
					        return task
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Controller(object):
 | 
					class Controller(object):
 | 
				
			||||||
    """Binds the model and the view together."""
 | 
					    """Binds the model and the view together."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, view):
 | 
					    def __init__(self, model):
 | 
				
			||||||
        self.model = Model()
 | 
					        self.model = model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_view(self, view):
 | 
				
			||||||
        self.view = view
 | 
					        self.view = view
 | 
				
			||||||
 | 
					        if isinstance(view, TkinterView):
 | 
				
			||||||
 | 
					            self.request_number_of_tasks_from_model()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def run(self):
 | 
					    def request_number_of_tasks_from_model(self):
 | 
				
			||||||
        """The controller's main function. Depending on what type of view is
 | 
					        number = len(self.model)
 | 
				
			||||||
        selected, a different event loop is setup. Do note that the ConsoleView
 | 
					        self.view.show_message("you have {} tasks".format(number))
 | 
				
			||||||
        is not a real event loop, just a basic flow of action."""
 | 
					 | 
				
			||||||
        if self.view is ConsoleView:
 | 
					 | 
				
			||||||
            self.view = self.view()
 | 
					 | 
				
			||||||
            self._run_console_view()
 | 
					 | 
				
			||||||
        elif self.view is TkinterView:
 | 
					 | 
				
			||||||
            root = Tk()
 | 
					 | 
				
			||||||
            root.title("Task Manager")
 | 
					 | 
				
			||||||
            root.geometry("500x300")
 | 
					 | 
				
			||||||
            self.view = self.view()
 | 
					 | 
				
			||||||
            self.view._set_controller(self)
 | 
					 | 
				
			||||||
            root.mainloop()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_task_from_model(self, idx):
 | 
					    def request_task_from_model(self, idx):
 | 
				
			||||||
        """Needed for the TkinterView to communicate with the controller."""
 | 
					        """Needed for the ConsoleView and TkinterView to communicate with the controller."""
 | 
				
			||||||
        task = self.model.get_task(idx)
 | 
					        task = self.model.get_task(idx)
 | 
				
			||||||
        self.view.show_task(task)
 | 
					        if task is None:
 | 
				
			||||||
 | 
					            self.view.error("task not found!")
 | 
				
			||||||
    def _run_console_view(self):
 | 
					        else:
 | 
				
			||||||
        """Super simple event loop."""
 | 
					 | 
				
			||||||
        while True:
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                idx = self.view.select_task()
 | 
					 | 
				
			||||||
                idx = int(idx)
 | 
					 | 
				
			||||||
            except Exception as e:
 | 
					 | 
				
			||||||
                self.view.error(e)
 | 
					 | 
				
			||||||
                continue
 | 
					 | 
				
			||||||
            task = self.model.get_task(idx)
 | 
					 | 
				
			||||||
            self.view.show(task)
 | 
					            self.view.show(task)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    view = TkinterView
 | 
					    model = Model()
 | 
				
			||||||
    app = Controller(view)
 | 
					    controller = Controller(model)
 | 
				
			||||||
    app.run()
 | 
					    view = ConsoleView(controller)
 | 
				
			||||||
 | 
					    controller.set_view(view)
 | 
				
			||||||
 | 
					    view.mainloop()
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Below you can see a `tkinter` class that acts as a drop in replacement for the `ConsoleView` class.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```python
 | 
				
			||||||
 | 
					class TkinterView(tk.Tk):
 | 
				
			||||||
 | 
					    def __init__(self, controller):
 | 
				
			||||||
 | 
					        tk.Tk.__init__(self)
 | 
				
			||||||
 | 
					        self.controller = controller
 | 
				
			||||||
 | 
					        self.title("hello world")
 | 
				
			||||||
 | 
					        self.geometry("500x400")
 | 
				
			||||||
 | 
					        self.resizable(0, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.header = tk.Label()
 | 
				
			||||||
 | 
					        self.header.grid(column=0, row=0, sticky=tk.W)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.question = tk.Label(self, text="Which task do you want to see?")
 | 
				
			||||||
 | 
					        self.question.grid(column=0, row=1, sticky=tk.W)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.input = tk.Entry(self)
 | 
				
			||||||
 | 
					        self.input.grid(column=1, row=1, sticky=tk.W)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.button = tk.Button(self, text="lookup", command=self.clicked)
 | 
				
			||||||
 | 
					        self.button.grid(column=0, row=2, sticky=tk.W)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.output = tk.Label(self, text="...")
 | 
				
			||||||
 | 
					        self.output.grid(column=1, row=2, sticky=tk.W)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def _is_entry_digit(self):
 | 
				
			||||||
 | 
					        number = self.input.get()
 | 
				
			||||||
 | 
					        if number.isdigit():
 | 
				
			||||||
 | 
					            number = int(number)
 | 
				
			||||||
 | 
					            return number
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clicked(self):
 | 
				
			||||||
 | 
					        number = self._is_entry_digit()
 | 
				
			||||||
 | 
					        if not number:
 | 
				
			||||||
 | 
					            msg = "numbers please..."
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            msg = self.controller.request_task_from_model(number)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def show_message(self, msg):
 | 
				
			||||||
 | 
					        self.header.config(text=msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def show(self, task):
 | 
				
			||||||
 | 
					        """Displays the task to the console. This method is called from the
 | 
				
			||||||
 | 
					        controller."""
 | 
				
			||||||
 | 
					        self.output.config(text=task)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def error(self, msg):
 | 
				
			||||||
 | 
					        """Prints error messages coming from the controller."""
 | 
				
			||||||
 | 
					        self.output.config(text=msg)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!--
 | 
				
			||||||
 | 
					
 | 
				
			||||||
For a GUI only login generator an implementation without MVC could look a bit like this.
 | 
					For a GUI only login generator an implementation without MVC could look a bit like this.
 | 
				
			||||||
Note that the actual calculation is done inside the window itself.
 | 
					Note that the actual calculation is done inside the window itself.
 | 
				
			||||||
This is not a good idea because we should separate responsibilities into classes!
 | 
					This is not a good idea because we should separate responsibilities into classes!
 | 
				
			||||||
| 
						 | 
					@ -964,10 +943,16 @@ if __name__ == "__main__":
 | 
				
			||||||
    app.mainloop()
 | 
					    app.mainloop()
 | 
				
			||||||
````
 | 
					````
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Coding challenge - Login generator with GUI
 | 
					## Coding challenge - Login generator with GUI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Coding challenge - Trivial pursuit with GUI
 | 
					## Coding challenge - Trivial pursuit with GUI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# WXpython
 | 
					# WXpython
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## wxpython helloworld
 | 
					## wxpython helloworld
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue