-3

I want to have a frame with a input box, when the submit button next to it is pressed it submits the input and calls the function Add_Label from class ChangedPage where the function is added under and then raises the next frame where I want the label to appear.

The problem is I want the function I call to add a widget to the second class not the class I am calling it from. I have made a new program to demonstrate this issue:

import tkinter as tk

class Creating_Stuff(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)


        container.pack(side="top", fill="both", expand = True)

        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        for F in (PageTwo, ChangedPage):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(PageTwo)

    def show_frame(self, cont):

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

class PageTwo(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        global bob

        self.tk_setPalette(background='#bbfff0', foreground='black',
               activeBackground='#d9d9d9', activeForeground='#ff9933')

        self.controller = controller

        title_2 = tk.Label(self, text= "Input Page #frame1", font = "Times 17 underline bold").place(relx = 0.5, rely = 0.1, relwidth = 0.4, anchor="center")

        self.ENTRY = tk.Entry(self,width = 10, bg='white', fg='Black')
        self.ENTRY.place(relx=0.5,rely=0.5,relwidth=0.3,anchor="center")

        self.submit_button_2 = tk.Button(self, text="Submit Request", bg='#f2f2f2', command= self.raising)
        self.submit_button_2.place(relx=0.4,rely=0.6,relwidth=0.2,anchor="center")

        ####Generic Stuff

        Exit = tk.Button(self, text ="Exit",command=lambda:destroy(),bg='#f2f2f2')
        Exit.place(relx=0.5,rely=(9/10), relwidth = 0.4, anchor="center")

    def raising(self):
        #Memes and stuff goes here
        global bob

        bob = self.ENTRY.get()
        ChangedPage.Add_Label(self)

        self.controller.show_frame(ChangedPage)

class ChangedPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        ###Main stuff for the frames

        self.title_27 = tk.Label(self, text= "Example Changed Page? #frame2", font = "Times 16 italic underline"
                                 ).place(relx = 0.36, rely = 0.05, relwidth = 0.4, anchor=tk.CENTER)

        ####Generic Stuff
        bk2_Menu2 = tk.Button(self, text="Back to start",
                            command=lambda: controller.show_frame(PageTwo),bg='#f2f2f2')
        bk2_Menu2.place(relx=0.5,rely=(0.8), relwidth = 0.2, anchor="center")


        Exit = tk.Button(self, text ="Exit",command=lambda:destroy(),bg='#f2f2f2')
        Exit.place(relx=0.5,rely=(9/10), relwidth = 0.4, anchor="center")

    def Add_Label(self):

        self.label1 = tk.Label(self, text= bob, font="Times 20")
        self.label1.place(anchor = tk.CENTER, relx = 0.5, rely = 0.5, relwidth = 0.2, relheight = 0.1)

app = Creating_Stuff()
def destroy():
    app.destroy()

app.tk_setPalette(background='#bbfff0', foreground='black',
       activeBackground='#d9d9d9', activeForeground='#ff9933')

app.title("Example Label Adding Program")
app.geometry("800x450")
app.mainloop()

The code I have shown is a program with the first page with input boxes when you submit it will take you to the next frame and run the function from class ChangedPagewhich is meant to make the label on the page that is just raised. Can anyone see what is going wrong?

Start Page is here:

Where it is meant to go here:

  • 2
    _"if you don't know what I am wanting...just read what I have tried to say here a couple of times!"_ - But why? I don't think it is very nice to make a unclear and/or hard to read question and then expect us to try to decipher what you're saying. Please take a bit of time to format your question in way that is easy to understand. That way, people will be more willing to help you. – Christian Dean Apr 06 '17 at 21:58
  • 2
    More specifically, a [mcve] that allows others to recreate the problem would be useful. See [ask]. – jonrsharpe Apr 06 '17 at 22:03
  • You don't need to wait for *"next time"*, please [edit] this one as suggested. – jonrsharpe Apr 07 '17 at 09:12
  • The phrase "run in the current class frame" doesn't make a lot of sense. Functions don't run "in" classes or frames. You can call functions on instances of classes. Is that what you mean? Unfortunately, the problem is in your code and you haven't shown enough code for us to reproduce the problem. As suggested by someone else, please read and follow the advice here: [How to create a Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve). – Bryan Oakley Apr 07 '17 at 11:40
  • @DestinyBob I'm not sure what you mean. I posted my previous comment on the very first version of your question. I have not made any comments about my understanding of your question _after_ your edits. That being said, after re-reading your question, You still missing a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). Without one, we really can't offer much more. – Christian Dean Apr 07 '17 at 15:46
  • Alright all, bear with I am revising the question hopefully conforming to your standards! – rob.wealthall Apr 07 '17 at 17:36
  • Your indentation is broken in the code – Bryan Oakley Apr 07 '17 at 21:24

2 Answers2

1

The first step is to update your controller to be able to return an instance of a page.

class Creating_Stuff(tk.Tk):
    ...
    def get_page(self, page_class):
        return self.frames[page_class]

Next, you need to call this function to get a reference to the instance which was created earlier, from which you can call the method:

class PageTwo(tk.Frame):
    ...
    def raising(self):
        ...
        changed_page = self.controller.get_page(ChangedPage)
        changed_page.AddLabel()
        ...
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
0

You are calling a class method, there is no instance attached for it to work on.

For example, to create class Creating_Stuff(tk.Tk): you use the code

app = Creating_Stuff()

This gives you an instance of Creating_Stuff called app. Hence you call app.destroy()

It may be you created an instance of class ChangedPage in some of the code you took out, but you don't refer to that instance.

At some point (probably in the __init__ of PageTwo) you'd need something like:

MyWorkingPage = ChangedPage()

and then in def raising(self):

MyWorkingPage.Add_Label()

self.controller.show_frame(MyWorkingPage)

Now the code will now which ChangedPage you want to display.

There are such things as staticmethod and classmethod, but they aren't what you want here.

Alan
  • 2,914
  • 2
  • 14
  • 26
  • In the code in the question, there is already an instance of `ChangedPage`; you shouldn't be creating a new instance. – Bryan Oakley Apr 07 '17 at 21:31
  • And yet I note in your answer you do exactly what I told him to do - create an instance to refer to. – Alan Apr 07 '17 at 21:37
  • no, you misunderstand the code. I am not creating an instance. Like I said in my answer, an instance already exists. My answer simply gets a reference to an existing instance. That's a significant difference. – Bryan Oakley Apr 07 '17 at 21:59
  • Yes, it is a significant difference. – Alan Apr 07 '17 at 22:16