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 import
ed:
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 import
s after the necessary contents of the files are declared/defined/initialized and have also replaced the #Code
s with pass
es.
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.