0

I'm writing a tkinter app that has 3 pages in three different .py files.

I've reworked the code to allow me to create each frame by running a main overarching app which is self.controller in all the subsequent pages (thanks to some excellent users on this site). The reason I have done this is that I want to be able to pass a user name (tk.StringVar()) from the first Frame to a tk.Label in the second Frame.

As I've said above I've rewritten this code a few times but still when I try to actually call a variable or a function from either of the other pages I get the error shown below.

The other page is called FrontPage and it's stored in front_page.py and when I run that page through the main tk.Tk it works perfectly so I know I have definied self.name_entry properly there.

The (minimum) code I'm using for the GamePage is

import tkinter as tk
from tkinter import SUNKEN
import front_page
from front_page import FrontPage
from character import Character
from dice_roll import Die


class GamePage(tk.Frame):
    """The overall class for the app"""

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="This is the start page")
        label.pack(side="top", fill="x", pady=10)
        self.features = {}

        #This is where I try to call the text from the other page
        self.character_name = front_page.FrontPage.name_entry.get()

        self.name_label = tk.Label(
            self.mainframe,
            text= self.character_name,
            font=("Courier", 20),
            bd = 1,
            relief = SUNKEN
        )
        self.name_label.pack()

When I try to actually call a the text from a tk.Entry on the FrontPage it doesn't work. All the functions from my other classes (which are imported up top) work fine.

Traceback (most recent call last):
  File "/Users/kevinomalley/Desktop/python_work/rapid_rpg/app_GUI.py",       
line 47, in <module>
    app = GUI()
  File "/Users/kevinomalley/Desktop/python_work/rapid_rpg/app_GUI.py", 
line 20, in __init__
    frame = F(parent=container, controller=self)
  File "/Users/kevinomalley/Desktop/python_work/rapid_rpg/main_page.py", 
line 23, in __init__
    self.character_name = front_page.FrontPage.name_entry.get()
AttributeError: type object 'FrontPage' has no attribute 'name_entry'

Now I'm 90% sure this is because I'm not using the self.controller properly I've seen loads of answers referencing it but no clear explanation about how to use it or effectively call it.

If anyone could free me from 5 days of beating my head against a wall it'd lift my poor little newbie heart.

Thanks

KevOMalley743
  • 551
  • 3
  • 20

1 Answers1

1

The controller is a way to control access between the pages. You haven't shown all your code, but if you're wanting your pages to be able to access other pages, the first think you need to do is create a function that can return a reference to another page.

For example:

class YourApp(...):
    ...
    def get_page(self, page_class):
        return self.frames[page_class]

Now, from any page, you can call this function to get a reference to any other page:

game_page = self.controller.get_page(GamePage)

With that reference, you can now use any of its attributes:. For example:

self.character_name = game_page.name_entry.get()

Note: these examples may not be 100% correct. I don't know how you've implemented the rest of your code. However, the concept is what is important:

  • add a method to a controller to return a page
  • call that method to get a reference to a page
  • use that reference to get attributes of that page

This is all explained in more detail in this answer: https://stackoverflow.com/a/33650527/7432

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Bryan, Thank you so much for this. I'm going to work through this to add it to my code. You're honestly like the tkinter whisperer man. I came across the answer you suggest a few days ago and it really helped but I seem to keep missing bits of it. I nkow you're probably crazy busy but if you ever wrote a tkinter tutorial it'd help a lot of people I'm sure. – KevOMalley743 Jul 31 '19 at 22:33