0

I'm new to Python and trying to understand the code below. This code should create 3 frame objects that can be rotated to the front to swap pages.
The APP class should create these 3 new objects. I'm not sure that it is.
What I am trying to be is modify a label on the Dashboard class through a function in that class. i.e. Dashboard.update() Can someone please explain how the APP class is creating frame objects for the 3 windows. I'm now sure that it is and I think I am trying to update text in the class and not a object of that class.

### Import libaries
import requests
import pyodbc 
import tkinter as tk
from tkinter import *
from tkinter import messagebox, ttk

### Set global fonts
TITLE_FONT = ("Verdana", 12)

### Define the applicaiton class
class APP (Frame):

    ### Build the init function to create the container and windows
    def __init__ (self, master=None ):

        Frame.__init__(self, master)
        self.grid()

        # Set the application window title
        self.master.title("Playing Around with Classes")

        # set the size of the row height for the application
        self.master.rowconfigure(0, weight=1)
        self.master.rowconfigure(1, weight=35)
        self.master.rowconfigure(2, weight=1)
        self.master.rowconfigure(3, weight=1) 

        #Row 0 - Title area
        label = tk.Label(master, text="Playing Around with Classes", font=TITLE_FONT)
        label.grid(row=0, columnspan=3, sticky="nsew")

        # Main presentation are
        Frame2 = Frame(master, bg="#263D42")
        Frame2.grid(row = 1, column = 0, rowspan = 1, columnspan = 3,  sticky = "nsew") 

        # List of pages
        self.frames = {}

        # i think this loop defines the class objects
        for F in (NetworkMap,AuthorPage,Dashboard):

            frame = F(Frame2, self)
            self.frames[F] = frame
            frame.grid(row=0, column=1, sticky="nsew")

        self.show_frame(Dashboard)

    ### Define the show_frame function that will bring the selected fram to the front so it can be viewed
    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()

### Create a class for the Dashboard page.  This will also be the start page when the application starts
class Dashboard (tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self,parent, bg="#263D42")
        label = tk.Label(self, text="Text to change", font=TITLE_FONT, bg="#263D42", fg="white", pady = 20)
        label.grid(row=0, column=0, sticky="nsew")

    def update(self):
        self.allPapersLabel.config(text="Changed Text")

### Create a page to get the Author detasil
class AuthorPage (tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self,parent)
        label = tk.Label(self, text="Get Author", font=TITLE_FONT)
        label.grid(row=0, column=0, sticky="nsew")

class NetworkMap (tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self,parent)
        label = tk.Label(self, text="Network Map", font=TITLE_FONT)
        label.grid(row=0, column=0, sticky="nsew")

def changeText():
    Dashboard.update()

changeText()

root = tk.Tk()
root.geometry("600x800+100+100")
app = APP(master=root)
app.mainloop()
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
Brian Knott
  • 21
  • 1
  • 2
  • For help in understanding the pieces of that code see [Tkinter! Understanding how to switch frames](https://stackoverflow.com/questions/34301300/tkinter-understanding-how-to-switch-frames) – Bryan Oakley Jun 02 '20 at 20:09

1 Answers1

1

Can someone please explain how the APP class is creating frame objects for the 3 windows

The crux is here:

for F in (NetworkMap,AuthorPage,Dashboard):
    frame = F(Frame2, self)
    self.frames[F] = frame
    frame.grid(row=0, column=1, sticky="nsew")

Keep in mind that NetworkMap, AuthorPage and Dashboard are classes. Classes are callables that function as a factory for new instances of the particular type.

So basically the for-loop makes F an alias (or label) for each of those classes and calls them in turn to instantiate an object.

Keep in mind that what we call "variables" in most languages are refered to as names in Python. From the language manual:

Names refer to objects. Names are introduced by name binding operations.

So F is nothing more than a handy label to refer to the three classes. The for-loop header binds the name to the classes.


BTW: This looks like a re-implementation of a ttk.Notebook. I would suggest to use that instead.


Edit

The frames are saved into the frames dictionary the App object. So in all of the methods of App instances you can access self.frames to get the individual frames.

The somewhat weird (to me at least) thing is that the class object of the frame is used as the key for selecting from the dictionary.

So using self.frames[AuthorPage] in methods of App should return the AuthorPage frame.

Roland Smith
  • 42,427
  • 3
  • 64
  • 94
  • OK Thanks. Does that mean that I can call the Dashboard class through the F variable. Something like F.update() to access the update function in the Dashboard Class? – Brian Knott Jun 02 '20 at 01:34
  • I just to add to what is above. Is the code description for each line below correct. Line below set the frame variable to equal the frame definition frame = F(Frame2, self) line below create the 3 objected based on the 3 classes self.frames[F] = frame The line below defined where the objects sit on the page. In this instance all together frame.grid(row=0, column=1, sticky="nsew") I still don't understand how I can reference a function inside one of these created objects. These objects seem to have no name. – Brian Knott Jun 02 '20 at 01:48
  • It's not a re-implementation of a ttk.notebook. It started as an answer to [a question](https://stackoverflow.com/questions/7546050/switch-between-two-frames-in-tkinter) a few years ago about how to switch between different frames. It's a terrible choice for beginners to start with, but a youtuber picked it up and created a tutorial that a lot of beginners seem to start with. – Bryan Oakley Jun 02 '20 at 20:07
  • @BryanOakley I was paraphrasing "Those who don't understand Unix are condemned to reinvent it, poorly." :-) To me, your linked answer (and this question) *basically* look like a Notebook without tabs. I fully agree that this is a much too complicated example to start with. I started writing GUI programs in C for OS/2 2.0 a long time ago, so the event driven nature of (most) GUI toolkits is old hat to me. But for newcomers I have found precious little python/tkinter material that clearly explains the nature of a GUI toolkit instead of just providing a code sample. – Roland Smith Jun 02 '20 at 22:18
  • @BryanOakley Even stronger, I am of the opinion that a Python novice should *not start* with tkinter programs *at all*. There is simply too much that simultaneously needs to be explained in that case. – Roland Smith Jun 02 '20 at 22:21
  • Thanks People. Got it sorted. Its not so much about the application, its more about developing my understanding what it is doing. – Brian Knott Jun 02 '20 at 23:00