2017-08-10 4 views
0

J'ai créé deux fenêtres dans tkinter et créé mes propres classes. La première fenêtre a un bouton qui appelle une autre fenêtre enfant. Le deuxième affichage de fenêtre enfant affiche une liste de tous les produits dans une base de données que j'ai faite. Le problème est que j'obtiens une AttributeError: l'objet 'EnterProducts' n'a pas d'attribut 'tree'. et l'arbre semble être affiché dans la première fenêtre plutôt que dans la seconde.Objets Python et Tree- AttributeError que je ne comprends pas et l'arbre apparaissant dans la mauvaise fenêtre

from tkinter import * 
from tkinter import ttk 
import sqlite3 


class Main(): 


    def __init__(self,master): 
     self.master = master 
     self.master.geometry('200x200+100+100') 
     self.master.title('Menu') 
     ttk.Style().configure("RB.TButton", background='blue', fg ='blue') 

     self.MainLabel=Label(self.master,text='IT Sales',fg='Blue', font=("Rage Italic", 44)).grid (row = 0, column = 4) 

     self.Products=ttk.Button(self.master,text="Products",width = 20, command=self.Products, style="RB.TButton").grid (row = 1, column = 4) 

    def Products(self): 
     root1=Toplevel(self.master) 
     myGUI1=EnterProducts(root1) 
     self.master.geometry('800x500+100+100') 


    def finish(self): 
     self.master.destroy() 

    class EnterProducts(): 

    def __init__(self,master): 

     db_name = 'sales.db' 

     self.master=master 
     self.master.geometry('400x200+100+200') 
     self.master.title('Product Details') 
     self.MainLabel = Label(self.master,text='All Products',fg='red').grid(row=0,column=0,columnspan=3,sticky=W) 

     self.Products=ttk.Button(self.master,text="Products",width = 20, command="", style="RB.TButton").grid (row = 1, column = 4) 
     self.viewing_records() 


    def run_query (self, query, parameters =()): 


     with sqlite3.connect(self.db_name) as conn: 
      cursor = conn.cursor() 
      query_result = cursor.execute (query, parameters) 
      conn.commit() 
     return query_result 

    def viewing_records(self): 
     tree=ttk.Treeview(height=10, columns=("Id ", "name", "Surname", "DOB")) 
     tree.grid(row=100, column=0, columnspan=100) 
     tree.heading('#0', text='ID', anchor=W) 
     tree.heading("#1", text='name', anchor=W) 
     tree.heading("#2", text='Surname', anchor=W) 
     tree.heading("#3", text='DOB', anchor=W) 

     records = self.tree.get_children() 
     for element in records: 
      self.tree.delete (element) 
      query = 'SELECT * FROM Products ' 
      db_rows = self.run_query (query) 
      for row in db_rows: 
       self.tree.insert ('', 1, values=(row[0], row[1], row[2], row[3])) 

    if __name__ == '__main__': 
     root=Tk() 
     main=Main(root) 
     root.mainloop() 

Répondre

0

Dans EnterProducts.viewing_records() un Treeview est créé et lié à la variable locale tree. Plusieurs lignes plus tard, une tentative est faite pour accéder à l'arbre en utilisant l'attribut d'instance self.tree qui fait référence à un autre. inexistant, variable par rapport à celui qui a été créé en tant que variable locale. Si vous souhaitez que l'arborescence reste dans l'instance EnterProducts, vous devez la traiter comme une variable d'instance, c'est-à-dire la lier à self.tree lors de sa création. Sinon, supprimez le self. de self.tree pour le traiter comme une variable locale.

+0

désolé comment le lier à self.tree – maz86

+0

Utilisez 'self.tree = ttk.Treeview (height = 10, colonnes = (" Id "," name "," nom "," DOB "))' et puis référencez-le avec 'self.tree' ailleurs. Vous pouvez également spécifier le widget parent pour 'Treeview' comme premier argument de son constructeur. – mhawke

+0

Je serais enclin à créer l'arbre dans 'EnterProducts .__ init __()', puis le remplir dans 'viewing_records()'. – mhawke