Sludge
Sludge

Reputation: 7385

Can't access variable from other class - tkinter

I'm attempting to write a program in tkinter where the user clicks on a button with their name and a verification page shows it to them. The problem I'm having is that the variable is either resetting or I'm accessing it wrong:

import tkinter as tk
from tkinter import *
from tkinter import ttk

LARGE_FONT = ("Times New Roman", 12)
NORM_FONT = ("Times New Roman", 10)
root = Tk()
root.withdraw()


class DIS(tk.Tk):

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

        tk.Tk.__init__(self, *args, **kwargs)
        tk.Tk.iconbitmap(self, default="")
        tk.Tk.wm_title(self, "program")
        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 (StartPage, contactQues, nameVerify):

            frame = F(container, self)

            self.frames[F] = frame

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

            self.show_frame(StartPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()


class StartPage(tk.Frame):

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

        button2 = ttk.Button(self, text = "Name Select",
                        command=lambda:           controller.show_frame(contactQues))
        button2.pack()


class contactQues(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)  
        self.controller = controller
        global name
        name = StringVar()

        label1 = tk.Label(self, text = "Select Your Name", font = LARGE_FONT)
        label1.pack(pady=10, padx=10)

        button2 = ttk.Button(self, text = "Bojangles", command = self.bojangles)
        button2.pack(pady=5)

    def bojangles(self):

        name.set("Mr. Bojangles")
        self.controller.show_frame(nameVerify)
    #
    #Many other names to select
    #

class nameVerify(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        namename = name.get()

        label5 = tk.Label(self, text = "Your Name:", font = LARGE_FONT)
        label5.pack(pady=10, padx=10)
        labelcontact = tk.Label(self, text = namename, font = NORM_FONT)
        labelcontact.pack()

app = DIS()
app.mainloop()

So, in essence, what I want to happen is: - Program runs and user presses "Name select", user selects their name, and the final page shows their selection.

I've tried messing with globals, textvariables for the labelcontact label, StringVar(), etc. and can't seem to peg this one down.

Is there a better way to do this? Or am I doing something inherently wrong?

Thank you for any help.

Upvotes: 1

Views: 1465

Answers (1)

Kevin
Kevin

Reputation: 76184

I suggest making name an attribute of the DIS class. Then your StartPage and nameVerify instances can access it via their controller attributes. If you want labelcontact to update automatically whenever name does, use the textvariable attribute.

Additionally, you need to delete your root = Tk() and root.withdraw() lines. I don't know why, but as long as they're there, the labelcontact Label won't properly update. They don't appear to do anything in any case - hopefully they aren't crucial to your actual code.

import tkinter as tk
from tkinter import *
from tkinter import ttk

LARGE_FONT = ("Times New Roman", 12)
NORM_FONT = ("Times New Roman", 10)

class DIS(tk.Tk):

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

        tk.Tk.__init__(self, *args, **kwargs)
        tk.Tk.iconbitmap(self, default="")
        tk.Tk.wm_title(self, "program")
        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.name = StringVar()
        self.frames = {}

        for F in (StartPage, contactQues, nameVerify):

            frame = F(container, self)

            self.frames[F] = frame

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

            self.show_frame(StartPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()


class StartPage(tk.Frame):

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

        button2 = ttk.Button(self, text = "Name Select",
                        command=lambda:           controller.show_frame(contactQues))
        button2.pack()


class contactQues(tk.Frame):

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

        label1 = tk.Label(self, text = "Select Your Name", font = LARGE_FONT)
        label1.pack(pady=10, padx=10)

        button2 = ttk.Button(self, text = "Bojangles", command = self.bojangles)
        button2.pack(pady=5)

    def bojangles(self):

        self.controller.name.set("Mr. Bojangles")
        self.controller.show_frame(nameVerify)
    #
    #Many other names to select
    #

class nameVerify(tk.Frame):

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

        label5 = tk.Label(self, text = "Your Name:", font = LARGE_FONT)
        label5.pack(pady=10, padx=10)
        labelcontact = tk.Label(self, textvariable = self.controller.name, font = NORM_FONT)
        labelcontact.pack()

app = DIS()
app.mainloop()

Upvotes: 1

Related Questions