Search code examples
pythontkinterattributeerrorself

Python Tkinter structured in a Class: Can methods be in an independent file?


I'm setting up a Tkinter GUI in what's becoming a rather long Python class with attributes toward the top and methods toward the bottom. To avoid the need for so much scrolling up and down, it would be convenient to separate the methods into an independent file. But I can't stumble upon the exact syntax to let the two files talk to each other as parts of one class. Snippets that follow are pared severely and edited.

GUI is defined in classExample.py:

# Imports from standard Python modules
import tkinter as tk
from tkinter import ttk

# Imports from custom app modules
import opus as op

# Graphical User Interface
class WC:

    def __init__(self, root, op):
        
        # Root window
        self.root = root

        # App structure: Notebook tab manager with two tabs
        self.nb = ttk.Notebook(self.root)
        self.tab1 = ttk.Frame(self.nb)
        self.nb.add(self.tab1, text="")
        self.tab2 = ttk.Frame(self.nb)
        self.nb.add(self.tab2, text="")
        self.nb.grid()

        # Tab two, structure: two Frames side by side, form and control
        self.tab2_form = ttk.Frame(self.tab2)
        self.tab2_ctrl = ttk.Frame(self.tab2)
        self.tab2_form.grid(row=0, column=0, padx=30, pady=10)
        self.tab2_ctrl.grid(row=0, column=1, padx=30, pady=10)
        ...

        # Tab two, "form" Frame: widgets
        ...
        self.country_input = tk.StringVar()
        self.country_box = ttk.Combobox(self.tab2_form, values=["Canada", "Mexico", "USA",], textvariable=self.country_input)
        self.country_box.grid(row=2, column=1, sticky=("N", "E", "S", "W"), padx=10, pady=5)
        self.country_box.bind("<<ComboboxSelected>>", op.set_country)
        ...
        self.root.mainloop()

if __name__ == "__main__":
    root = tk.Tk()
    WC(root, op)
    root.mainloop()

Method is defined in custom module opus.py:

from classExample import WC as wc

# Methods that operate with user data
country = ""
def set_country(self):
    country = wc.country_input.get()


Solution

  • Code in opus.py that worked with classExample.py above:

    # Methods that operate with user data
    country = ""
    def set_country(self):
        country = self.widget.get()
        print(f"Country: {country}")