0

I'm currently working on a project with Tkinter, where I wish to have the buttons in the StartPage bring me to PageOne with the button text as the label.

I tried creating a function that changes a global variable and has PageOne access the global variable but it does not seem to work as class MiniProject is only running once.

So I tried to associate a Tkinter String Variable with the PageOne label instead but I am not sure how to go about doing it. How can I link the two classes together? Or should I place PageOne under StartPage as a function?

Please advise.

#code layout from https://pythonprogramming.net/change-show-new-frame-tkinter/
import tkinter as tk

class MiniProject(tk.Tk): #baseline code for adding/switching pages

    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 (StartPage, PageOne):

            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): #Front page with buttons A-D
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        for letter in ["A","B","C","D"]: #clicking button should bring me to PageOne with label as button text
            button = tk.Button(self, text = letter, command = lambda j = letter:\
                                [PageOne.changename(j),controller.show_frame(PageOne)])
            button.pack()

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

        my_string_var = tk.StringVar()
        my_string_var.set("Default Text")

        label = tk.Label(self, textvariable = my_string_var) #Supposed to display button number
        label.pack(pady=10,padx=10)
        button1 = tk.Button(self, text = "TO HOME", command = lambda: controller.show_frame(StartPage))
        button1.pack()
    def changename(name):
        my_string_var.set(name)

app = MiniProject()
app.mainloop()

Receiving Traceback

Exception in Tkinter callback
Traceback (most recent call last):
  File "/Users/kohtziyong/anaconda3/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
    return self.func(*args)
  File "<ipython-input-3-3405dd392652>", line 37, in <lambda>
    [PageOne.changename(j),controller.show_frame(PageOne)])
  File "<ipython-input-3-3405dd392652>", line 52, in changename
    my_string_var.set(name)
NameError: name 'my_string_var' is not defined


  • So it should be changename(j) instead of changename(x)? Either way, when I try to access the PageOne label text=var, it does not show me 5 or the button number that I pressed. Does this have anything to do with the __init__ function in my first class MiniProject? – Tzi Yong Koh Nov 02 '19 at 11:49
  • ***"So it should be `changename(j)`"***: Yes. About ***"`PageOne label text=var`***: First you have to understand [Event-driven programming](https://stackoverflow.com/a/9343402/7414759). This: `tk.Label(self, text=var)` is done **once** and not at every `show_frame(...`. You can associate a Tkinter variable with the `PageOne Label`. Read [The Tkinter Label Widget](http://effbot.org/tkinterbook/label.htm). – stovfl Nov 02 '19 at 13:29
  • I see! How should I go about associating a Tkinter variable with `PageOne Label`? Should I change the format of my code by placing `PageOne` under `StartPage`? I've edited my code by associating StringVar but I am receiving a Traceback Error. – Tzi Yong Koh Nov 02 '19 at 18:05
  • ***`NameError: name 'my_string_var' is not defined`***: `my_string_var` have to be a `class attribute`. Take the tour at [Python - Object Oriented](https://www.tutorialspoint.com/python/python_classes_objects.htm) – stovfl Nov 02 '19 at 18:10
  • Use this approach: [`Button text`](https://stackoverflow.com/a/55735566/7414759) – stovfl Nov 02 '19 at 18:19

0 Answers0