Python Forum
How can I access objects or widgets from one class in another class?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How can I access objects or widgets from one class in another class?
#1
Here I am working with two different tkinter frame classes, in which I am trying to access the combobox widget service_list from the retrieve frame class, inside a method in the frame class menu, so that I may configure the values of the combobox.
Now my question is, how can I do so without running into a NameError or AttributeError?

import tkinter as tk
from customtkinter import CTkComboBox, CTkTextbox
from .backend import *

class retrieve(tk.Frame):
    def __init__(self, parent, controller):
        self.controller = controller
        tk.Frame.__init__(self, parent, bg="black", highlightthickness=5, highlightcolor='white')
        self.controller = controller
        head = tk.Label(self, bg="black", fg="white", text="STORED DATA",
                        font=("Terminal", 32))    
        services = self.controller.services
        data = self.controller.data
        data_disp = CTkTextbox(self, fg_color="black", text_color="white", font=("Terminal", 22, "bold"),
                          scrollbar_button_color="white", scrollbar_button_hover_color="white",wrap=tk.WORD,
                            corner_radius=0, width=450, height=250, border_width=0)
        def combobox_callback(choice):
            i = services.index(choice)
            result = str(data[i])
            data_disp.configure(state=tk.NORMAL)
            data_disp.delete("0.0", tk.END)
            data_disp.insert("0.0", result)
            data_disp.configure(state=tk.DISABLED)
            print("combobox dropdown clicked:", choice)    
        service_list = CTkComboBox(self, fg_color="black", text_color="white", font=("Terminal", 20, "bold"), justify="left",
                              corner_radius=0, width=450, height=36, border_width=0, border_color="white", 
                              command=combobox_callback, dropdown_fg_color="black", dropdown_text_color="white", 
                              dropdown_font=("Terminal", 20, "bold"),hover=False, button_color="black", 
                              button_hover_color="white", dropdown_hover_color="black")
        service_list.set(">SERVICE NAME")  
        back = tk.Button(self,
                          bg="black", fg="white",
                          text='BACK', font=("Terminal", 18, "bold"),
                          command=lambda: controller.show_frame(page_name="menu", username=self.controller.username, services=self.controller.services, data=self.controller.data),
                          activebackground="black",
                          relief=tk.SOLID,
                          borderwidth=0,
                          padx=16, pady=0, cursor="hand2")
        entNote = tk.Label(self,bg="black", fg="white", text="(enter)",
                           font=("Terminal", 10))

        head.place(relx=0.5, rely=0.1, anchor=tk.CENTER)
        service_list.place(relx=0.1, rely=0.3, y=-10,x=-35,anchor=tk.W)
        data_disp.place(relx=0.1, rely=0.45, x=-30, y=65,anchor=tk.W)
        back.place(relx=0.5, rely=0.9, anchor=tk.CENTER)
        entNote.place(relx=0.5, rely=0.9, y=20, anchor=tk.CENTER)
        controller.exitButton(self)
        controller.homeButton(self) 
        
    def binds(self):
        self.focus_set()
        self.controller.bind('<Return>', lambda x: self.controller.show_frame(page_name="menu", username=self.controller.username, services=self.controller.services, data=self.controller.data))
import tkinter as tk
from .backend import *
from .retrieve import *

class menu(tk.Frame):
    def __init__(self, parent, controller):
        self.controller = controller
        tk.Frame.__init__(self, parent, bg="black", highlightthickness=5, highlightcolor='white')
        self.controller = controller
        head = tk.Label(self, bg="black", fg="white", text="MENU",
                        font=("Terminal", 32))
        save = tk.Button(self,
                          bg="black", fg="white",
                          text='STORE DATA', font=("Terminal", 20, "bold"),
                          command=lambda: controller.show_frame(page_name="store", username=self.controller.username, services=self.controller.services, data=self.controller.data),
                          activebackground="black",
                          relief=tk.SOLID,
                          borderwidth=0,
                          padx=16, pady=7, cursor="hand2")
        def extract_data():
            services, data = retrieve_passwords(self.controller.username)
            # TRYING TO ACCESS THE COMBOBOX WIDGET FROM RETRIEVE CLASS SO AS TO CONFIGURE ITS PROPERTIES
            retrieve1 = retrieve()
            retrieve1.service_list.configure(values=services)
            # ===================================================
            self.controller.show_frame(page_name="retrieve", 
                                  username=self.controller.username, 
                                  services=services, data=data)
        retrieve_but = tk.Button(self,
                          bg="black", fg="white",
                          text='RETRIEVE DATA', font=("Terminal", 18, "bold"),
                          command=lambda: extract_data(),
                          activebackground="black",
                          relief=tk.SOLID,
                          borderwidth=0,
                          padx=16, pady=7, cursor="hand2")

        head.place(relx=0.5, rely=0.1, anchor=tk.CENTER)
        save.place(relx=0.5, rely=0.4, anchor=tk.CENTER)
        retrieve_but.place(relx=0.5, rely=0.6, anchor=tk.CENTER)
        controller.exitButton(self)
        controller.homeButton(self) 
        
    def binds(self):
        self.focus_set()
Reply
#2
Instead of
service_list = …
Use
self.service_list = …
That is to say make service_list a member of the retriever object.

Avoid import * by all means. It obfuscates the code. Also try to follow PEP 8 coding style.
Reply
#3
(Aug-05-2023, 06:27 PM)Gribouillis Wrote: Instead of
service_list = …
Use
self.service_list = …
That is to say make service_list a member of the retriever object.

Avoid import * by all means. It obfuscates the code. Also try to follow PEP 8 coding style.

Looks like it did work because no errors and I can access the object service_list. But somehow I cant seem to configure its values with the list services, everytime I click the retrieve_but in the menu frame
Reply
#4
Nevermind, looks like it was just a type error. Because after back testing a little bit, it seems like the method retrieve_passwords was returning a tuple instead of a list which was required to be fed into the widget values
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How does this code create a class? Pedroski55 6 444 Apr-21-2024, 06:15 AM
Last Post: Gribouillis
  class definition and problem with a method HerrAyas 2 271 Apr-01-2024, 03:34 PM
Last Post: HerrAyas
  Printing out incidence values for Class Object SquderDragon 3 304 Apr-01-2024, 07:52 AM
Last Post: SquderDragon
  class and runtime akbarza 4 400 Mar-16-2024, 01:32 PM
Last Post: deanhystad
  Operation result class SirDonkey 6 569 Feb-25-2024, 10:53 AM
Last Post: Gribouillis
  The function of double underscore back and front in a class function name? Pedroski55 9 684 Feb-19-2024, 03:51 PM
Last Post: deanhystad
  super() and order of running method in class inheritance akbarza 7 778 Feb-04-2024, 09:35 AM
Last Post: Gribouillis
  Class test : good way to split methods into several files paul18fr 4 491 Jan-30-2024, 11:46 AM
Last Post: Pedroski55
  Good class design - with a Snake game as an example bear 1 1,845 Jan-24-2024, 08:36 AM
Last Post: annakenna
  question about __repr__ in a class akbarza 4 621 Jan-12-2024, 11:22 AM
Last Post: DeaD_EyE

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020