Home > Net >  Tkinter interface does call Function in Main code
Tkinter interface does call Function in Main code

Time:07-12

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.

  • Related