0

This is the smaller version of my bigger program. When I hit the "Forward" Button on "Week 1", it should print "Hi, from Week 2", however it's still printing "Hi, from Week 1."

Just to make sure I am assigning the correct button widget because this widget appeared at several places, So I used the line below just to test and it worked to the specific widget that I want.

self.parent.parent.sheet_dict["Week2"].upper_tabs_dict["Final"].button.configure(text = "red")

I don't know why my forward(self): function is not working.

Thanks for taking the time to assist me in this.

Here is the complete code:

import tkinter as tk
from tkinter import ttk
from functools import partial

class Application(tk.Tk):
    def  __init__(self):
        super().__init__()
        self.title("notbook my own try")
        self.geometry("700x450")
        self.config(bg="tan")

        self.style = ttk.Style() # instantce of ttk.Style() class.
        self.lnb = Sheets(self) #composition (application has child)

class Sheets(ttk.Notebook): #contains the weeks tabs
    def __init__(self, parent): #parent is root, which is tk.
        parent.style.configure("down.TNotebook", tabposition="sw")
        super().__init__(parent, style = "down.TNotebook")# this parent   
               is Notebook class.
        self.pack(fill = tk.BOTH, expand =1)
        self.parent = parent

        self.week_index = ['Week 1', 'Week 2',"Week 3", "Week 4"] #
        self.sheet_dict = {} #holds all the One_Weekly_Notebook's 
                     instances

        for week in (self.week_index):
            self.week = One_Weekly_Notebook(self)#create instances
            self.week.pack()
            self.add(self.week, text = week)
            self.pack()
            self.sheet_dict[week] = self.week


class One_Weekly_Notebook(ttk.Notebook): #contains the tabs
    def __init__(self, parent):
        super().__init__(parent)
        self.pack(fill = tk.BOTH, expand =1)
        self.parent = parent

        self.upper_tabs_dict = {}
        self.calculate_buttons_dict = {} #to store all the calculate 
                  buttons in differnt weeks

        self.object_final = Final(self)
        self.object_requests = Requests(self)
        self.object_control = Control(self)

        tab1 = self.object_final #child of lower notebook
        tab2 = self.object_requests
        tab3 = self.object_control
        tab1.pack()
        tab2.pack()
        tab3.pack()

        self.add(tab1, text = "Final")
        self.pack()
        self.add(tab2, text = 'Requests')
        self.pack()
        self.add(tab3, text = 'Control')
        self.pack()

        self.upper_tabs_dict["Final"] = tab1
        self.upper_tabs_dict["Requests"] = tab2
        self.upper_tabs_dict["Control"] = tab3

    def display_results(self, button): #layer 3
        self.say_hi(button)

    def say_hi(self,button): #layer 3
         self.id =    
        self.parent.parent.lnb.index(self.parent.parent.lnb.select())+1
#             button=     
        self.parent.parent.lnb.index(self.parent.parent.lnb.select())+1
        print (f"Hi from {button}")#current tap #)

class Final(tk.Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.pack(fill=tk.BOTH, expand=1)
        self.parent = parent


        self.buttons()
    def buttons(self):
        self.button = tk.Button(self, text="Say Hi", bg="salmon")
        self.button.configure(command= lambda button=self.button:    
           self.parent.display_results(button))
        self.button.pack()
        self.parent.calculate_buttons_dict = self.button

        self.buttonc = tk.Button(self, text = "Forward", command =   
           self.forward)
        self.buttonc.pack()


        print (self.parent.calculate_buttons_dict)

    def forward(self):
        self.parent.display_results(self.parent.parent.sheet_dict["Week   
            1"].upper_tabs_dict["Final"].button)
        self.parent.display_results(self.parent.parent.sheet_dict["Week 
            2"].upper_tabs_dict["Final"].button)
        self.parent.display_results(self.parent.parent.sheet_dict["Week 
            3"].upper_tabs_dict["Final"].button)
        self.parent.display_results(self.parent.parent.sheet_dict["Week 
           4"].upper_tabs_dict["Final"].button)

class Requests(Final):
    pass

class Control(tk.Frame):
    pass

if __name__ == '__main__':
    Application().mainloop()


enter code here
fishtang
  • 167
  • 3
  • 9
  • 3
    Possible duplicate of [Why is Button parameter “command” executed when declared?](https://stackoverflow.com/questions/5767228/why-is-button-parameter-command-executed-when-declared) – Aran-Fey May 15 '19 at 08:24
  • hi @Aran-Fey, i read the post from the link. I don't want to pass a value. I just want to run function. also, i was thinking, am i not assigning the command to the right button? thanks. – fishtang May 15 '19 at 23:03
  • It is clearly explained in the linked post that you need to pass a reference to a function, regardless of whether you need to pass a value or not. You got it right on `self.buttonc`, but you need to fix your `forward` method. – Henry Yik May 16 '19 at 07:33
  • @HenryYik let me read it again. maybe I missed something. thanks for the tip on the forward method. – fishtang May 16 '19 at 07:48
  • hi @HenryYik I read a few more times, according to the Brian Oakley "To pass a reference you must use the name only, without using parenthesis or arguments...." I took the parenthesis out and still does not work. I am just confused. other parts of the posts always has "argument" in the function. i also read the link from the efbot, and I understood all of that. they have parameters in the function. anymore hint you can give me? thanks. – fishtang May 17 '19 at 01:32
  • Your button config is so nested, I can't get where it is pointing to. And `does not work` is not describing the problem - is it throwing an error? Is it doing nothing? – Henry Yik May 17 '19 at 03:06
  • hi @HenryYik Yes, it looks complicated, but everything is dictionary. Let me explain. this is a button: self.parent.parent.sheet_dict["Week 1"].upper_tabs_dict["Final"]. this is also a button: self.parent.parent.sheet_dict["Week 2"].upper_tabs_dict["Final"]. when i hit the "Forward" button, it should run the "def forward" function, which ideally should print "Hi from 1", "Hi from 2", "hi from 3" and "Hi from 4", all together. As it is written right now, when I hit the "Forward" button, nothing happens. thanks again. – fishtang May 17 '19 at 07:25
  • Look at your `forward` function again. All it does is alter the text and command of the nested button - it does not do any printing. – Henry Yik May 17 '19 at 07:33
  • @HenryYik yes. the first line in the forward function is to test that I am working on the specific button(widget), which i know it works and I am calling on the right button. the 2nd line is where I am having trouble. it does nothing. this is where I need the help. I have been reading on lambda function, but i don't know how to set it up. the reason for the multilayer tab set up is because in each tab(week) there are whole bunch pulp calculation going on and ideally, I want to do all the calculation in one shot per tab with one button. – fishtang May 17 '19 at 07:44

1 Answers1

0

I still can't fully understand what are you trying to achieve, but let's break down to smaller pieces.

First, in your current forward function:

self.parent.parent.sheet_dict["Week 2"].upper_tabs_dict["Final"].button.configure(command= self.parent.display_results)

This only modifies the button command. From the looks of it, you want to execute the command instead. If so, just call the method directly:

self.parent.parent.sheet_dict["Week 2"].display_results()

Next, you also said you expect to print "Hi, from Week 2" when you hit the "Forward" Button on "Week 1", but it's still printing "Hi, from Week 1". There is actually how you coded it right now and its behaving as it should. From your say_hi method:

print (f"Hi from {self.parent.parent.lnb.index(self.parent.parent.lnb.select())+1}")

You are looking up the index of the current notebook. Therefore it will always print the current tab index even you specified sheet_dict["Week 2"].

My suggestion is to include the index in the first place when you create your Notebook:

class Sheets(ttk.Notebook):
    def __init__(self, parent):
        ...
        for num, week in enumerate(self.week_index,1): #pass an index, starting from 1
            self.week = One_Weekly_Notebook(self,num)
            self.week.pack()
            self.add(self.week, text = week)
            self.pack()
            self.sheet_dict[week] = self.week

class One_Weekly_Notebook(ttk.Notebook):
    def __init__(self, parent,index):
        super().__init__(parent)
        self.pack(fill = tk.BOTH, expand =1)
        self.index = index #store the index as an attribute
        self.parent = parent
        ...

    def say_hi(self): #layer 3
        print (f"Hi from {self.index}")

Then it should always return the correct index as specified in your forward method.

Henry Yik
  • 22,275
  • 4
  • 18
  • 40
  • hi @HenryYik, thanks for taking the time to clarify with detail on my code. I updated based on your recommendation, however that forward function is not doing what i need. it's printing just like the say hi function, which is showing the same tab. any other hint or ideas? – fishtang May 18 '19 at 07:25
  • Hi@HenryYik, I was able to print out the widgets themselves not the value. I don't know what else to do after that. I will keep researching, if I can find a solution, I will update again. – fishtang May 20 '19 at 06:45