Hi guys I'm making a Python3 program that makes some ZPL tags. And I have two codes, one with the main code and another with the Interface (that I use Tkinter to make it). So my problem is that my Interface is not working well with the main code. So, it's confusion so the code main is:
from ctypes import cast
import requests
import shutil
import sys
import csv
import os
from tkinter import *
from classGui import ProgGui
modelo_etiqueta_mm =[
[20,35], [30,75], [50,105]
]
modelo_etiqueta_in =[
[0.787402,1.37795], [1.1811,2.95276], [1.9685,4.13386]
]
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'base_produtos.csv')
def main_shell():
# Code
def ProgGui():
pass
def cria_etiqueta(pos_coluna, pos_linha, produto, cod_barra):
#Code
def busca_produto(p_cod_produto):
#Code
def cria_linha(p_qtd_etiqueta,p_cod_produto, p_linhas):
#Code
def cria_zpl(p_cod_produto, p_qtd_etiqueta, p_modelo_etiqueta):
#Code
def geraPdf():
#Code
if __name__ == '__main__':
print(sys.argv)
# separa a execução, se chamar com parametro é execução por shell
if len(sys.argv) >= 2: # aqui fazes a verificacao sobre quantos args queres receber, o nome do programa conta como 1
print('Execução de shell.')
main_shell()
else :
print('Execução com Interface')
gui = ProgGui()
#gui.mainloop()
# encerra execução
sys.exit()
And the Ui is:
from tkinter import *
from tkinter import ttk
class ProgGui:
"""docstring for ClassName"""
def __init__(self, master):
self.master = master
super().__init__()
quantEtiquetas = IntVar()
codInt = IntVar()
master.title('Etiquetas')
master.geometry('500x200')
self.pad = ttk.Frame(app, padding=100)
self.nomeProg = ttk.Label(app, text="Etiquetas").grid(sticky='E')
self.etqTxt = ttk.Label(app, text="Cod do produto").grid(column=0, row=1 )
self.quanTxt = ttk.Label(app, text="Quant de etiquetas").grid(column=0, row=2)
self.entryCod = ttk.Entry(app, textvariable=codInt).grid(column=1, row=1, padx=20, pady=20)
self.entryqantEtiquetas = ttk.Entry(app, textvariable=quantEtiquetas).grid(column=1, row=2, padx=20, pady=20)
self.btnQuit = ttk.Button(app, text="Quit", command=app.destroy).grid(column=1, row=3)
self.btnPdf = ttk.Button(app, text="Gera Pdf", command= geraPdf).grid(column=0, row=3)
app = Tk()
tela = ProgGui(app)
app.mainloop()
So when I run the main it does not work and give the error:
Traceback (most recent call last):
File "zpl_printer_test_object.py", line 40, in <module>
from classGui import ProgGui
File "/home/user/eclipse-workspace/etiqueta/classGui.py", line 39, in <module>
tela = ProgGui(app)
File "/home/user/eclipse-workspace/etiqueta/classGui.py", line 35, in __init__
self.btnPdf = ttk.Button(app, text="Gera Pdf", command= geraPdf).grid(column=0, row=3)
NameError: name 'geraPdf' is not defined
I don't know why this is happening, because the func geraPdf exists in the main code, but the Ui doesn't "see" the func. How can I make this work? Thank you guys!
Btw I'm using Linux Mint 19.3
CodePudding user response:
This is caused by the circular import of MainClass's contents in classGui.py and classGui's ProgGui in MainClass.py. (Both the files are dependent on each other)
As both the files are importing each other's contents (functions like geraPdf() and classes like ProgGui) before they're initialized, you get the ImportError.
I've changed where they're imported:
MainClass.py:
from ctypes import cast
import requests
import shutil
import sys
import csv
import os
from tkinter import *
modelo_etiqueta_mm =[
[20,35], [30,75], [50,105]
]
modelo_etiqueta_in =[
[0.787402,1.37795], [1.1811,2.95276], [1.9685,4.13386]
]
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'base_produtos.csv')
def main_shell():
pass
def ProgGui():
pass
def cria_etiqueta(pos_coluna, pos_linha, produto, cod_barra):
pass
def busca_produto(p_cod_produto):
pass
def cria_linha(p_qtd_etiqueta,p_cod_produto, p_linhas):
pass
def cria_zpl(p_cod_produto, p_qtd_etiqueta, p_modelo_etiqueta):
pass
def geraPdf():
pass
from classGui import ProgGui #moved it here, so the functions are initialized before they're imported/used
if __name__ == '__main__':
print(sys.argv)
# separa a execução, se chamar com parametro é execução por shell
if len(sys.argv) >= 2: # aqui fazes a verificacao sobre quantos args queres receber, o nome do programa conta como 1
print('Execução de shell.')
main_shell()
else :
print('Execução com Interface')
gui = ProgGui()
#gui.mainloop()
# encerra execução
sys.exit()
classGui.py:
from tkinter import *
from tkinter import ttk
class ProgGui:
"""docstring for ClassName"""
def __init__(self, master):
self.master = master
super().__init__()
quantEtiquetas = IntVar()
codInt = IntVar()
master.title('Etiquetas')
master.geometry('500x200')
self.pad = ttk.Frame(app, padding=100)
self.nomeProg = ttk.Label(app, text="Etiquetas").grid(sticky='E')
self.etqTxt = ttk.Label(app, text="Cod do produto").grid(column=0, row=1)
self.quanTxt = ttk.Label(app, text="Quant de etiquetas").grid(column=0, row=2)
self.entryCod = ttk.Entry(app, textvariable=codInt).grid(column=1, row=1, padx=20, pady=20)
self.entryqantEtiquetas = ttk.Entry(app, textvariable=quantEtiquetas).grid(column=1, row=2, padx=20, pady=20)
self.btnQuit = ttk.Button(app, text="Quit", command=app.destroy).grid(column=1, row=3)
self.btnPdf = ttk.Button(app, text="Gera Pdf", command=geraPdf).grid(column=0, row=3)
from MainClass import * #moved it here, so the ProgGui class is initialized before it's imported/used
app = Tk()
tela = ProgGui(app)
app.mainloop()
I've moved the imports after the necessary contents of the files are declared/defined/initialized and have also replaced the #Codes with passes.
MainClass.py is your main file, and classGui.py has the main UI.
See ImportError: Cannot import name X and https://stackoverflow.com/a/59384553/16136190.
I've tested it, and it works for me.
