Import class from another file, but element name is not defined (executable example)

enter image description here

The 3 example files executable are: main.py, page1.py and external_class.py. The main.py file is used to start the main GUI and the page1.py file contains the class in which I import another class from the external_class.py file.

The problem is that the External class of the external_class.py file is unable to execute an element of the Page1 class of the page1.py file. The element is obtained from the combobox present in the Page1 class of the page1.py file, so I don't want to rewrite the code from scratch in the External class of the external_class.py file, but I just want the External class to recognize the select_only_way element.

In the External class of the external_class.py file, I use select_only_way like this self.cursor.execute ('SELECT a, b FROM other WHERE a = ?', [Select_only_way]). The problem is right here, in the External class of the external_class.py file.

I get error in the External class of the external_class.py file.

    self.cursor.execute('SELECT a, b FROM other WHERE a= =?', [select_only_way])
NameError: name 'select_only_way' is not defined

ADDITIONAL DETAILS

The main.py file and the page1.py file are both located in the same main folder/home/xxx/Desktop/Folder. While the external_class.py file is in the same folder, but it is inside another, which is contained within another folder, so /home/xxx/Desktop/Folder/Folder2/Folder3/external_class.py

main.py

import tkinter as tk
from tkinter import ttk
from PIL import ImageTk
from page1 import Page1
from page2 import Page2

root = tk.Tk()
root.geometry('480x320')

topbar = tk.Frame(root, bg='#e10a0a', height=43)
topbar.pack(fill='x')

style = ttk.Style()
style.theme_use('default') # select a theme that allows configuration of ttk.Notebook
# put the tabs at the left with white background
style.configure('TNotebook', tabposition='wn', background='white', tabmargins=0)
# configure tab with white background initially, yellow background when selected
style.configure('TNotebook.Tab', background='white', width=10, focuscolor='yellow', borderwidth=0)
style.map('TNotebook.Tab', background=[('selected', 'yellow')])

nb = ttk.Notebook(root)
nb.pack(fill='both', expand=1)


page1 = Page1(nb)
page2 = Page2(nb, bg='pink', bd=0)

nb.add(page1, text='aaaaa', compound='left')
nb.add(page2, text='bbbbb', compound='left')


root.mainloop()

page1.py

import tkinter as tk
from tkinter import ttk
from Folder.Folder import external_class
import sqlite3

class Page1(tk.Frame):
    def __init__(self, master, **kw):
        super().__init__(master, **kw)

  
        conn = sqlite3.connect('/...')
        cursor = conn.cursor() 

        #COMBOBOX
        def combo_ticket(event=None):
            cursor.execute('SELECT ticket FROM aaa')
            values = [row[0] for row in cursor]    
            return values

        ticket=ttk.Combobox(self, width = 15)
        ticket.place(x=10, y=10)
        ticket.set("Ticket Way")
        ticket['value'] = combo_ticket()
        ticket.bind('<<ComboboxSelected>>', combo_ticket)

        select_tricket= ticket.get()
        select_only_way= select_tricket.split('>>>')[0]


        def click():
            k = external_class.External(self.textbox) 
 
        #TEXTOBOX
        self.textbox = tk.Text(self, width=33, height=10, font=('helvetic', 12))
        self.textbox.place(x=30, y=40)

        #BUTTON
        button = tk.Button(self, text="Ok", command= lambda: [click()])
        button.pack()

external_class.py

import sqlite3

class External:
    def __init__(self, textbox): # added textbox argument
 

        self.conn = sqlite3.connect('/...')
        self.cursor = self.conn.cursor()

        self.cursor.execute('SELECT a, b FROM other WHERE a =?', [select_only_way])
        self.element = self.cursor.fetchone()

        #condition to print text in the textbox of the main.py file
        if (self.element and self.element[0] == "try1"):
            textbox.insert("end", "ok")
        else:
            textbox.insert("end", "no")

The database, simplified by way of example, but working is:

#Combobox Table aaa
CREATE TABLE "aaa" (
    "id"    INTEGER,
    "ticket"    INTEGER, #for example "Madrid>>>Tokyo"
    PRIMARY KEY("id" AUTOINCREMENT)
);

#other Table
CREATE TABLE "other" (
    "id"    INTEGER,
    "a" INTEGER, #for example "try1"
    "b" INTEGER, #for example "try2"
    PRIMARY KEY("id" AUTOINCREMENT)
);

How can I solve? I know the problem and I know the reason for the error, but I'm new to python and don't know how to fix. Do you have solutions to show me? Thanks a lot in advance to those who will answer.


Solution 1:

The basic problem is that you have not created a reference to the attribute. First of all, care should be taken to prefix all attributes inside a new object (class Page1 __init__) with self. in front of all attributes. This makes the value part of the object and can be called after the initialization. In your case, the entire class could be passed as an argument to External.

class Page1(tk.Frame):
    def __init__(self, master, **kw):
        super().__init__(master, **kw)
        ...
        self.select_only_way = select_tricket.split('>>>')[0]
        ...
        def click():
            k = external_class.External(self)
        ...
class External:
    def __init__(self, Page1): # added textbox argument
        ...
        self.cursor.execute('SELECT a, b FROM other WHERE a =?', [Page1.select_only_way])
        ...
        if (self.element and self.element[0] == "try1"):
            Page1.textbox.insert("end", "ok")
        ...