J'ai fait un petit écran de connexion. Après avoir entré les informations d'identification, je veux que le Tkinter soit fermé et ouvre un nouveau fichier python. Si vous exécutez le code ci-dessous, il me donnera l'erreur NameError: name ttk is not defined. Dans l'autre fichier, j'ai tout importé et je lui ai donné le nom correct.

Le fichier que j'utilise pour la connexion:

from tkinter import *
import tkinter.messagebox as tm

class LoginFrame(Frame):
    def __init__(self, master):
        super().__init__(master)

        self.label_username = Label(self, text="Username")
        self.label_password = Label(self, text="Password")
        self.photo = PhotoImage(file="sbshreg.png")

        self.label_image = Label(root, image=self.photo)
        self.label_image.image = self.photo

        self.entry_username = Entry(self)
        self.entry_password = Entry(self, show="*")

        self.label_username.grid(row=0, sticky=E)
        self.label_password.grid(row=1, sticky=E)
        self.label_image.grid(row=3, column=2, rowspan=2, columnspan=2, sticky=W, padx=10)

        self.entry_username.grid(row=0, column=1, sticky=E)
        self.entry_password.grid(row=1, column=1, sticky=E)

        self.logbtn = Button(self, text="Login", command=self._login_btn_clicked)
        self.logbtn.grid(columnspan=2, column=1, row=2, sticky=S+E+N+W)

        self.grid()

    def _login_btn_clicked(self):
        username = self.entry_username.get()
        password = self.entry_password.get()

        if username == "123" and password == "123":
            tm.showinfo("SBSHREG", "Welcome 123")
            #The sweet spot where all goes wrong...
            self.destroy()
            exec(open("./BatchFrame.py").read())
        else:
            tm.showerror("SBSHREG", "Incorrect username")

root = Tk()
root.title("SBSHREG")
root.geometry("235x120")
lf = LoginFrame(root)
root.mainloop()

Dans l'autre fichier, j'ai obtenu ceci: from tkinter import ttk as ttk qui devrait empêcher l'erreur de l'autre fichier de se produire.

from tkinter import *
import tkinter.messagebox as tm
from tkinter import ttk as ttk

class BatchFrame(Frame):
    def __init__(self, master):
        super().__init__(master)

        self.photo = PhotoImage(file="sbshreg.png")
        self.label_photo = Label(root, image=self.photo)
        self.label_photo.image = self.photo

        self.label_photo.grid(row=0, column=2, sticky=N, padx=10, pady=10)

        #Add frame starting here
        frame = LabelFrame(self.master, text='Voeg batch toe')
        frame.grid (row=0, column=0, padx=10)

        self.label_batch = Label(frame, text="Batchnummer")
        self.label_employee = Label(frame, text="Medewerker")
        self.label_material = Label(frame, text="Materiaalsoort")
        self.label_weight = Label(frame, text="Gewicht")

        self.entry_batch = Entry(frame)
        self.entry_employee = Entry(frame)
        self.entry_material= Entry(frame)
        self.entry_weight = Entry(frame)

        self.label_batch.grid(row=0, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
        self.label_employee.grid(row=2, column=0,  sticky=S+E+N+W, columnspan=2, padx=10)
        self.label_material.grid(row=4, column=0,  sticky=S+E+N+W, columnspan=2, padx=10)
        self.label_weight.grid(row=6, column=0,  sticky=S+E+N+W, columnspan=2, padx=10)

        self.entry_batch.grid(row=1, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
        self.entry_employee.grid(row=3, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
        self.entry_material.grid(row=5, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
        self.entry_weight.grid(row=7, column=0, sticky=S+E+N+W, columnspan=2, padx=10)

        self.btnadd = Button(frame, text='Voeg toe', command=self._btn_add_clicked)
        self.btnadd.grid(column=0, row=8, pady=10)

        #Search frame starting here
        framesearch = LabelFrame(self.master, text='Zoek')
        framesearch.grid(row=0, column=1, sticky=N)

        self.label_batch = Label(framesearch, text="Batchnummer")
        self.label_employee = Label(framesearch, text="Medewerker")

        self.entry_batch = Entry(framesearch)
        self.entry_employee = Entry(framesearch)

        self.label_batch.grid(row=0, column=0, sticky=S, columnspan=2, padx=10)
        self.label_employee.grid(row=2, column=0, sticky=S, columnspan=2, padx=10)

        self.entry_batch.grid(row=1, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)
        self.entry_employee.grid(row=3, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)

        self.btnbatch = Button(framesearch, text="Zoek", command=self._btn_batch_clicked)
        self.btnemployee = Button(framesearch, text="Zoek", command=self._btn_employee_clicked)

        self.btnbatch.grid(columnspan=1, column=2, row=1, sticky=W, padx=10)
        self.btnemployee.grid(columnspan=1, column=2, row=3, sticky=W, padx=10)

        #This is the viewingarea for the data
        self.tree = ttk.Treeview (height=10, columns=("Batchnummer", "Medewerker", "Materiaalsoort", "Gewicht"))
        self.tree.grid (row=9, columnspan=10, padx=10, pady=10)
        self.tree.heading('#1', text='Batchnummer', anchor=W)
        self.tree.heading('#2', text='Medewerker', anchor=W)
        self.tree.heading('#3', text='Materiaalsoort', anchor=W)
        self.tree.heading('#4', text='Gewicht', anchor=W)
        self.tree.column('#0', stretch=NO, minwidth=0, width=0)
        self.tree.column('#1', stretch=NO, minwidth=0, width=100)
        self.tree.column('#2', stretch=NO, minwidth=0, width=100)
        self.tree.column('#3', stretch=NO, minwidth=0, width=100)
        self.tree.column('#4', stretch=NO, minwidth=0, width=100)

        self.grid()

    def _btn_add_clicked(self):
        batch = self.entry_batch.get()

    def _btn_batch_clicked(self):
        batch = self.entry_batch.get()

    def _btn_employee_clicked(self):
        batch = self.entry_employee.get()


root = Tk()
root.title("SBSHREG")
root.geometry("432x480")
lf = BatchFrame(root)
root.mainloop()

Si je change self.destroy() en root.destroy(), j'obtiens l'erreur suivante: _tkinter.TclError: can't invoke "label" command: application has been destroyed. Dans le deuxième fichier, les fonctions ne sont pas encore terminées car je travaille toujours sur le fichier, mais cela ne devrait pas avoir d'impact sur l'erreur.

J'ai cherché partout et j'ai essayé beaucoup et je n'ai toujours aucune idée de quoi que ce soit ...

2
Lauk-k 16 avril 2018 à 15:58

3 réponses

Meilleure réponse

Envisagez d'initialiser les cadres dans une classe de niveau supérieur, GUI , qui gère l'ouverture des deux cadres où LoginFrame appelle la méthode open_batch() (maintenant lambda implémentée) de son parent. Ci-dessous suppose que LoginFrame.py et BatchFrame.py réside dans le même dossier que le script GUI_App .

De cette façon, les scripts s'exécutent en tant que modules autonomes sur une instance Tk().

GUIApp (appelle les cadres enfants, LoginFrame et BatchFrame)

from tkinter import *
import LoginFrame as LF
import BatchFrame as BF

class GUI():

    def __init__(self):    
        self.root = Tk()
        self.root.title("SBSHREG")
        self.root.geometry("235x120")

        self.root.open_batch = self.open_batch

        lf = LF.LoginFrame(self.root)
        self.root.mainloop()

    def open_batch(self):
        bf = BF.BatchFrame(self.root)

app = GUI()

LoginFrame

from tkinter import *
import tkinter.messagebox as tm

class LoginFrame(Frame):

    def __init__(self, master):
        super().__init__(master)

        self.label_username = Label(self, text="Username")
        self.label_password = Label(self, text="Password")
        self.photo = PhotoImage(file="sbshreg.png")

        self.label_image = Label(self, image=self.photo)
        self.label_image.image = self.photo

        self.entry_username = Entry(self)
        self.entry_password = Entry(self, show="*")

        self.label_image.grid(row=0, column=2, rowspan=2, columnspan=2, sticky=W, padx=10)
        self.label_username.grid(row=2, sticky=E)
        self.label_password.grid(row=3, sticky=E)

        self.entry_username.grid(row=2, column=1, sticky=E)
        self.entry_password.grid(row=3, column=1, sticky=E)

        self.logbtn = Button(self, text="Login", command=lambda: self._login_btn_clicked(master))
        self.logbtn.grid(row=4, column=1, columnspan=2, sticky=S+E+N+W)

        self.grid()

    def _login_btn_clicked(self, controller):
        username = self.entry_username.get()
        password = self.entry_password.get()

        if username == "123" and password == "123":
            tm.showinfo("SBSHREG", "Welcome 123")

            self.destroy()
            controller.open_batch()
        else:
            tm.showerror("SBSHREG", "Incorrect username")

BatchFrame

from tkinter import *
import tkinter.messagebox as tm
from tkinter import ttk as ttk

class BatchFrame(Frame):

    def __init__(self, master):
        super().__init__(master)    

        self.photo = PhotoImage(file="sbshreg.png")
        self.label_photo = Label(master, image=self.photo)
        self.label_photo.image = self.photo

        self.label_photo.grid(row=0, column=2, sticky=N, padx=10, pady=10)

        #Add frame starting here
        frame = LabelFrame(master, text='Voeg batch toe')
        frame.grid (row=0, column=0, padx=10)

        self.label_batch = Label(frame, text="Batchnummer")
        self.label_employee = Label(frame, text="Medewerker")
        self.label_material = Label(frame, text="Materiaalsoort")
        self.label_weight = Label(frame, text="Gewicht")

        self.entry_batch = Entry(frame)
        self.entry_employee = Entry(frame)
        self.entry_material= Entry(frame)
        self.entry_weight = Entry(frame)

        self.label_batch.grid(row=0, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
        self.label_employee.grid(row=2, column=0,  sticky=S+E+N+W, columnspan=2, padx=10)
        self.label_material.grid(row=4, column=0,  sticky=S+E+N+W, columnspan=2, padx=10)
        self.label_weight.grid(row=6, column=0,  sticky=S+E+N+W, columnspan=2, padx=10)

        self.entry_batch.grid(row=1, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
        self.entry_employee.grid(row=3, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
        self.entry_material.grid(row=5, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
        self.entry_weight.grid(row=7, column=0, sticky=S+E+N+W, columnspan=2, padx=10)

        self.btnadd = Button(frame, text='Voeg toe', command=self._btn_add_clicked)
        self.btnadd.grid(column=0, row=8, pady=10)

        #Search frame starting here
        framesearch = LabelFrame(master, text='Zoek')
        framesearch.grid(row=0, column=1, sticky=N)

        self.label_batch = Label(framesearch, text="Batchnummer")
        self.label_employee = Label(framesearch, text="Medewerker")

        self.entry_batch = Entry(framesearch)
        self.entry_employee = Entry(framesearch)

        self.label_batch.grid(row=0, column=0, sticky=S, columnspan=2, padx=10)
        self.label_employee.grid(row=2, column=0, sticky=S, columnspan=2, padx=10)

        self.entry_batch.grid(row=1, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)
        self.entry_employee.grid(row=3, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)

        self.btnbatch = Button(framesearch, text="Zoek", command=self._btn_batch_clicked)
        self.btnemployee = Button(framesearch, text="Zoek", command=self._btn_employee_clicked)

        self.btnbatch.grid(columnspan=1, column=2, row=1, sticky=W, padx=10)
        self.btnemployee.grid(columnspan=1, column=2, row=3, sticky=W, padx=10)

        #This is the viewingarea for the data
        self.tree = ttk.Treeview (height=10, columns=("Batchnummer", "Medewerker", "Materiaalsoort", "Gewicht"))
        self.tree.grid (row=9, columnspan=10, padx=10, pady=10)
        self.tree.heading('#1', text='Batchnummer', anchor=W)
        self.tree.heading('#2', text='Medewerker', anchor=W)
        self.tree.heading('#3', text='Materiaalsoort', anchor=W)
        self.tree.heading('#4', text='Gewicht', anchor=W)
        self.tree.column('#0', stretch=NO, minwidth=0, width=0)
        self.tree.column('#1', stretch=NO, minwidth=0, width=100)
        self.tree.column('#2', stretch=NO, minwidth=0, width=100)
        self.tree.column('#3', stretch=NO, minwidth=0, width=100)
        self.tree.column('#4', stretch=NO, minwidth=0, width=100)

        self.grid()

    def _btn_add_clicked(self):
        batch = self.entry_batch.get()

    def _btn_batch_clicked(self):
        batch = self.entry_batch.get()

    def _btn_employee_clicked(self):
        batch = self.entry_employee.get()
2
Parfait 16 avril 2018 à 17:29

Je recommande d'importer batchframe au lieu de l'exécuter.

from tkinter import *
import tkinter.messagebox as tm
from tkinter import ttk as ttk
from batchframe import BatchFrame

class LoginFrame(Frame):
    def __init__(self, master):
        super().__init__(master)
        self.master = master

        self.label_username = Label(self, text="Username")
        self.label_password = Label(self, text="Password")
        self.photo = PhotoImage(file="icon.png")

        self.label_image = Label(root, image=self.photo)
        self.label_image.image = self.photo

        self.entry_username = Entry(self)
        self.entry_password = Entry(self, show="*")

        self.label_username.grid(row=0, sticky=E)
        self.label_password.grid(row=1, sticky=E)
        self.label_image.grid(row=3, column=2, rowspan=2, columnspan=2, sticky=W, padx=10)

        self.entry_username.grid(row=0, column=1, sticky=E)
        self.entry_password.grid(row=1, column=1, sticky=E)

        self.logbtn = Button(self, text="Login", command=self._login_btn_clicked)
        self.logbtn.grid(columnspan=2, column=1, row=2, sticky=S+E+N+W)

        self.grid()

    def _login_btn_clicked(self):
        username = self.entry_username.get()
        password = self.entry_password.get()

        if username == "123" and password == "123":
            tm.showinfo("SBSHREG", "Welcome 123")
            #The sweet spot where all goes wrong...
            self.destroy()
            # Create the instance of the BatchFrame class, passing in self.master
            self.batchframe = BatchFrame(self.master)
        else:
            tm.showerror("SBSHREG", "Incorrect username")

Puis, dans batchframe.py, changez la référence de variable de root à master

0
Ron Norris 16 avril 2018 à 13:30

Je ne suis pas d'accord avec la méthode selon laquelle vous invoquez votre 2ème fichier python. Vous n'avez vraiment pas besoin d'utiliser exec ici.

Cependant, si vous le souhaitez, vous devez ajouter import tkinter.ttk as ttk à votre première page pour que cela fonctionne correctement.

Votre meilleure option est d'importer le 2e fichier sur le 1er fichier et de l'invoquer en appelant le nom de la classe.

Donc pour vos importations sur la première page, vous devez ajouter import BatchFrame.

Appelez-le ensuite dans votre code.

Remplacer:

exec(open("./test2.py").read())

Avec:

BatchFrame.BatchFrame(root)

Je vois une erreur dans votre pensée de classe BatchFrame.

Change ça:

self.label_photo = Label(root, image=self.photo)

Pour ça:

self.label_photo = Label(master, image=self.photo)

MISE À JOUR: Pour résoudre votre problème à partir du commentaire, procédez comme suit:

1: Ajoutez ceci à votre classe BatchFrame:

class BatchFrame(Frame):
    def __init__(self, master):
        super().__init__(master)
        self.master = master # add this
        self.master.title("SBSHREG") # and this
        self.master.geometry("432x480") # and this

2: supprimez-le de votre fichier BatchFrame:

root = Tk()
root.title("SBSHREG")
root.geometry("432x480")
lf = BatchFrame(root)
root.mainloop()

3: Ajoutez ceci à votre classe LoginFrame:

class LoginFrame(Frame):
    def __init__(self, master):
        super().__init__(master)
        self.master = master # add this

4: Dans la classe LoginFrame, changez ceci:

BatchFrame.BatchFrame(root)

Pour ça:

BatchFrame.BatchFrame(self.master)
1
Mike - SMT 16 avril 2018 à 14:42