Import from other py file works in simple cripts but not in gui program

i have some python scripts using same functions, so i put them in a sepeparate help,py file
and in the main file I write from hlep import *. That works great.

No I have GUI with tk and ttk program that works fine but got quite big. So I tried the same putting somw common function to another py file and included it the same way, but now the the functions are not found, why?

to clear this a little bit, My main program starts with

import sys
import tkinter as tk
from tkinter import ttk
from pathlib import Path as pd
from tkinter import filedialog as fd
from tkinter.messagebox import showinfo
import os
import re
import subprocess
from ca_sub import *   # tis is the file with the exported funktions

root = tk.Tk()
root.title("Create CA and certs")

root.geometry('1100x600')  # x, y
# Create Main Frame
main_frame = ttk.Frame(root)
main_frame.pack(fill=tk.BOTH, expand=1)

this is ca_sub.py

# creates entry should be OK
def create_entry (row_nr, l_text, l_col, e_size, text_var):
    l_name = ttk.Label(data_frame, text=l_text, justify="left", width=len(l_text))  # create a label first
    l_name.grid(row=row_nr, column=l_col, padx=pad_x, pady=pad_y)  # define position
    e_name = ttk.Entry(data_frame, width=e_size, justify="left", textvariable=text_var)  # create the entry
    e_name.grid(row=row_nr, column=l_col + 1, padx=pad_x, pady=pad_y)  # define position

as long this function is in my main program everything works fine
when is ist in ca_sub.py
i get an error runing the theprogram as soon tis function is used, see screenshot

The error message is very clear. The function create_entry is attempting to a refer to a module named ttk, but that module does not exist in the module ca_sub.

When you put code into its own source file, you create a new module, and that module does not share the global namespace (modules, variables, etc.) with the module which imports it. It is not the same as copy-pasting the code from ca_sub into the main program.

At a minimum, you’ll need an import statement in ca_sub which imports ttk, but you may need other things too.

2 Likes

If I understand right, thats not just an include, as I as beginner and the experiance I made in the other scripts assumed. Thank you for that info. Have a nice sunday

Sorry me again
I imported all tk and ttk modules I use, but now it complains “data_frame” which is the window my input fields are in

Hello,

there are actually a few issues with this approach. Notice that in order for the function create_entry to work, you have to import the main module into the ca_sub.py module since you need to reference the data_frame as the root for the newly created entries. However, at the same time, you want to import the ca_sub.py module into your main module to import the create_entry function. What you have here is a race condition (a la which came first, the chicken or the egg). If you didn’t have this cross dependency (because of the root reference requirement), then it would work.

The other issue is that the create_entry function requires the values for pad_x and pad_y which are currently missing as parameters in the function definition.

An approach that might make more sense is writing this as a class based GUI application. You will have encapsulation whereby all local attributes will be visible to all methods (i.e., functions) via the self object reference.

2 Likes

What is if i pass the data_frame as a parameter and put the values for pad_x and pad_y to the sub module. So I may use the sub_module for other projects.
Background of these functions, I have some of them, for label, entry, combo box, etc., to easy and flexible create input fields

Thank you

Ok, I made a mistake when testing your script. There were errors in the script that you provided as written that I misinterpreted as related to the importation of the module. It turns out that you don’t have to import the main module into the second module where the function is located for the root reference.

Here are the two test scripts whereby you can test the app and verify for yourself.

# abc_1.py
# import tkinter as tk
from tkinter import ttk

# creates entry should be OK
def create_entry(root, row_nr, l_text, l_col, e_size, text_var, pad_x, pad_y):
    l_name = ttk.Label(root, text=l_text, justify="left", width=len(l_text))    # create a label first
    l_name.grid(row=row_nr, column=l_col, padx=pad_x, pady=pad_y)                 # define position
    e_name = ttk.Entry(root, width=e_size, justify="left", textvariable=text_var) # create the entry
    e_name.grid(row=row_nr, column=l_col + 1, padx=pad_x, pady=pad_y)             # define position

and finally …

# abc_2.py
import tkinter as tk
from tkinter import ttk

from abc_1 import create_entry

root = tk.Tk()
root.title("Create CA and certs")

root.geometry('500x300')  # x, y
# Create Main Frame
main_frame = ttk.Frame(root)
##main_frame.pack(fill=tk.BOTH, expand=1)

create_entry(root, 1, 'My Label Here', 1, 10, 1, 2, 5)

Note that when creating windows with tk, it is generally advised to stick with one form of widget placement (be it .grid, .pack, etc., but don’t mix and match).

Run the module abc_2.py. It should work now.

Hope this helps.

1 Like

Thank you, I appreciate your help. The project is now nearly 1050 lines. So I would put common functions in an other Module.
What it does is creating a self signed CA and then the posibility to create as much server certificates as you liked signed by this CA. i did something similar some years ago as a shell script, but thats not so comfortable.
The reason is some people have more or less internal servers and or web sites. When accessing that browser give warning or decline access. So if you put such a certificate to your website, an add the CA to you browser so it will not complain andusers will have no problem- Till here it works. The next step will be a possiliby of renewing a certificate as I did it with the shell script. When it is readyand testet I will put it on GitHub.
Good Evening, I will test you suggestion tomorrow

This is correct, it’s not actually anything like an include at all. If you’re familiar with other programming languages, it’s more similar to using a library: import just makes the code from the other module accessible.

2 Likes