'Print the result obtained from an external window but without opening the window (the selected checkboxes are automatically saved in the database)

enter image description here I have an external window (windows_option.py) that correctly prints a result in the textbox after hitting the Print external button. No problem here. Everything is OK!

Considering that the external window stores the selected checkboxes in the database (with 0 o 1), I would like to be able to print the result in the main window (page1.py) without having to open the external window. So I would like to click on the "Print main" button in the main window (page1.py) and print the result in the textobox of the main window. As a result I have eliminated the Print external button of the secondary window.

The difficulty I'm having is with the function to retrieve the already saved and selected checkboxes in the external window and print them. This function was done correctly in the external window, but I have now copied it to the main window (page1.py) and associated it with the "Print main" button. Considering that funclist and func are in the external window (windows_option.py), I thought that to call them I would need to import their function (def clicked).

NOTE: You can download the directly executable and bootable project on this reliable upload site

UPDATE: I believe that even solving the problem of importing the classes, I would not be able to print the result in the textbox of the main window. The reason is that I initially created a single window where you can select the checkboxes and print them, so the code was built that way. Next I thought about making it a secondary window and displaying its result in the main window. In the comments they pointed out to me that the code should be rewritten from scratch. Who can help me? Thank you

I reduce the problem to a small example:

page1.py (main windows)

import windows_option
from windows_option import form 

    class Page1(tk.Frame):
        def __init__(self, master, **kw):
            super().__init__(master, **kw)
    
            x = windows_option.Option1
            y = x.clicked(self) 
    
            #BUTTON FUNCTION
            def aaa():
                if y.funclist and all(func() for func in y.funclist): 
                    textbox.insert("end", "Ok")
    
            #TEXTOBOX
            textbox = tk.Text(self, width=33, height=10, font=('helvetic', 12))
            textbox.place(x=30, y=40)
    
            #BUTTON
            button = tk.Button(self, text="Print main", command= lambda: [aaa()])
            button.place(x=10, y=10)

But I encounter an error when I call them back:

AttributeError: module 'windows_option' has no attribute 'Option1'

More precisely the complete error is:

Traceback (most recent call last):
  File "/usr/lib/python3.8/idlelib/run.py", line 559, in runcode
    exec(code, self.locals)
  File "/home/dragomir/Desktop/folder/main.py", line 23, in <module>
    page1 = Page1(nb)
  File "/home/dragomir/Desktop/folder/page1.py", line 17, in __init__
    x = windows_option.Option1
AttributeError: module 'windows_option' has no attribute 'Option1'

I don't know if to correct this problem and my idea of ​​importing the function is the right solution to print the result of the external window in the textbox of the main window. If I go wrong, do you have any ideas other than the one I have illustrated?

WHERE SHOULD I GET THE RESULT OF THE EXTERNAL WINDOW FROM? I show you how to print the result in the textbox of the external window (considering now that I have removed the aaa function and pasted it in the main window). This code does not need to be modified, so I am only showing it as an example to show you where I should get the result from.

IMPORTANT: If someone can fix it, can they keep my base code without making too many changes? I am referring to checkboxes and checkbox functions. Do not change them, as I would like to keep the checkboxes separate individually (not grouped or in a for loop). So also their relative separate functions, each assigned to the checkbox. In short, as I wrote in the code. Do not modify the checkboxes and checkbox functions

windows_option.py (external windows)

import sqlite3
from tkinter import *
from tkinter import ttk
import tkinter as tk
import tkinter.font as tkFont
from tkinter import ttk
from PIL import ImageTk

import tkinter.messagebox
from tkinter import messagebox


def form(parent):
    opz = tk.Toplevel(parent)
    opz.title("Option")
    opz.geometry("500x400")
    opz.config(bg="white")
    opz.state("normal")
    opz.transient(parent)

    class Option1(tk.Frame):
        def __init__(self, master, **kw):
            super().__init__(master, **kw)
            self.configure(bg='white')

            chk_lst = []
            fn_lst = [] 
            funclist = set()

            Checkbutton1 = tk.IntVar()
            Checkbutton2 = tk.IntVar()
            Checkbutton3 = tk.IntVar()

            #CHECKBOX'S FUNCTIONS
            def Button1_func():
                if 5 + 3 == 8:
                    return True
                else:
                    return False

            def Button2_func():
                if 5 + 3 == 7:
                    return True
                else:
                    return False

            def Button3_func():
                if 5 + 3 == 8:
                    return True
                else:
                    return False

            def clicked(flag, func):
                if flag:
                    funclist.add(func)
                else:
                    funclist.remove(func)


            #CHECKBOX
            Button1 = tk.Checkbutton(self, text = "Checkbox 1", variable = Checkbutton1, onvalue = 1, offvalue = 0, height = 1,
                                     bg="white", foreground='black', activebackground="white",
                                     command=lambda: clicked(Checkbutton1.get(), Button1_func))
            Button1.place(x=10, y=36)

            Button2 = tk.Checkbutton(self, text = "Checkbox 2", variable = Checkbutton2, onvalue = 1, offvalue = 0, height = 1,
                                     bg="white", foreground='black', activebackground="white",
                                     command=lambda: clicked(Checkbutton2.get(), Button2_func))
            Button2.place(x=10, y=66)

            Button3 = tk.Checkbutton(self, text = "Checkbox 3", variable = Checkbutton3, onvalue = 1, offvalue = 0, height = 1,
                                     bg="white", foreground='black', activebackground="white",
                                     command=lambda: clicked(Checkbutton3.get(), Button3_func))
            Button3.place(x=10, y=146)

            chk_lst.extend([Checkbutton1, Checkbutton2, Checkbutton3])
            fn_lst.extend([Button1_func, Button2_func, Button3_func])


            #SAVE IN DATABASE
            def save():
                conn = sqlite3.connect("database")
                c = conn.cursor()

                for idx,chk_btn in enumerate(chk_lst,start=1):
                    c.execute(f'SELECT button1 FROM table1 WHERE id=?',(idx,))
                    rec = c.fetchall()

                    if rec:
                        c.execute("UPDATE table1 SET Button1=? WHERE id=?;", (chk_btn.get(),idx))
                    else:
                        c.execute("INSERT INTO table1 VALUES (?,?,?);", (idx,chk_btn.get()))
                    
                conn.commit()
                conn.close()

                messagebox.showinfo('SAVE', 'Saved successfully')


            #LOAD WHEN OPEN WINDOWS
            def load():
                conn = sqlite3.connect("/database") 
                c = conn.cursor()
                c.execute("SELECT * FROM table1")
                vals = c.fetchall()

                for val, chk_btn, func in zip(vals, chk_lst, fn_lst):
                    chk_btn.set(val[1])
                    
                    if val[1] == '1':    
                        funclist.add(func)

                conn.close()


            #BUTTON FUNCTION
            def aaa():
                # if need to clear the text box, uncomment below line
                #textbox.delete("1.0", "end")
                if funclist and all(func() for func in funclist): 
                    textbox.insert("end", "Ok")


            #SAVE BUTTON
            save = tk.Button(self, text="Save", bg='#b40909', foreground='white', command= save)
            save.place(x=10, y=10)

            #TEXTOBOX
            textbox = tk.Text(self, width=33, height=10, font=('helvetic', 12))
            textbox.place(x=10, y=220)

            #PRINT BUTTON
            button = tk.Button(self, text="Print", command= lambda: [aaa()])
            button.place(x=100, y=10)

            load()


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

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


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

    page1 = Option1(nb)
    nb.add(page1, text='Option 1', compound='left')
    opz.mainloop()

main.py (Window that opens the project)

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

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)

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

root.mainloop()


Solution 1:[1]

These could work:

  1. when you did

     from windows_option import form
    

    You did not actually call it.

    Try adding this:

     from form import Option1
    
  2. Instead of doing this:

     x = windows_option.Option1
    

    Try to do this:

     x = form.Option1
    

    As Option1 is inside form!!!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Peter Mortensen