Tkinter error 'list' object has no attribute 'get'

0

I need to make a program that asks for a number "Number of generators" and by clicking on the "accept" button, create a list with the number of spaces equal to the one entered, in addition to creating a matrix of 0 of the dimension before mentioned, until then everything works

Now I need that when you enter the values in the list and give "Calculate" these values replace the values of the diagonal of the matrix, try using a for to read number by number in the list and replace it in the matrix, but I get the following error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python36\lib\tkinter\__init__.py", line 1550, in __call__
    return self.func(*args)
  File "C:/matrices.py", line 87, in BaseD
    matriz_v[(i),(i)]=Barras[i].get()
AttributeError: 'list' object has no attribute 'get'

and I do not know how to solve the problem, I hope you can help me

import numpy
from tkinter import *

#crear las tablas   
def Tabla():

    def BaseD():
        global matriz_v

        for i in range(0,m):
            matriz_v[(i),(i)]=Barras[i].get()   
        print(matriz_v)    


    m = n_generadores.get()
    matriz_v = numpy.zeros((m,m))
    print(matriz_v)
    #TABLAS
    ventData.geometry("1500x600+0+0")
    lbld_generadores=Label(ventData,text="Datos de los generadores: ",font=(14)).grid(row=4,column=0)

    #NUMERO DE LA BARRA DONDE SE UBICARA EL GENERADOR
    n_Barra=["Barra"]
    #Creacion de la fila de etiquetas BARRA
    for i in range(len(n_Barra)):
        Label(ventData,text=n_Barra[i],bg="LightSteelBlue2",font=(12),relief=GROOVE,padx=10,pady=5).grid(row=4,column=i+1)
    #crear las filas de acuerdo al numero de barras ingresadas
    filasB=n_generadores.get()
    Barras=[]
    for i in range(filasB):
        Barras.append([0]*len(n_Barra))
        for j in range(len(n_Barra)):
            Barras[i][j]=("B"+str(i)+str(j))
            Barras[i][j]=DoubleVar()
            Entry(ventData,textvariable=Barras[i][j],width=16,bg="beige").grid(row=i+5,column=j+1)


#CALCULAR
    btnCreaBD=Button(ventData,text="Calcular",font=(14),command=BaseD,padx=10,pady=1).grid(row=filasB+7,column=1)
    lblVacia=Label(ventData,text="").grid(row=filasB+8,column=2)

#Ventana inicial
ventData=Tk()
ventData.geometry("800x400+0+0")
ventData.title("DESPACHO ECONOMICO")

lbln_generadores=Label(ventData,text="Número de Generadores: ",font=(16)).grid(row=1,column=0)

#Parametro de entrada - numero de generadores
n_generadores=IntVar()

txtBarras=Entry(ventData,textvariable=n_generadores).grid(row=2,column=0)

#Boton Aceptar
btnn_generadores=Button(ventData,text="Aceptar",font=(14),command=Tabla,padx=10,pady=1).grid(row=2,column=1)

#Insertar fila vacia
lblVacia=Label(ventData,text="").grid(row=2,column=2)

ventData.mainloop()   
    
asked by Luis Hugo Barrera Luna 10.06.2017 в 20:46
source

2 answers

0

If you want to take the element that is in a certain position in the list, just make lista[indice] . The lists do not have the attribute get() , those are the dictionaries if I'm not wrong.

    
answered by 10.06.2017 в 21:16
0

You have enough problems in the code:

  • The error jumps because Barras is a list of two dimensions, Barras[i] returns a nested list, not one of the Tkinter variables inside it.

  • On the other hand, you can not define the BaseD function within the Tabla function if you intend to call it by pressing the button. This function has a very short life, it is created when you call Tabla and when Tabla returns BaseD ceases to exist, so you can not call it later.

  • In addition, you will need Tablas to be a global variable to access it from the two functions.

Apart from this, two notes:

  • Using from módulo import * to import is a bad practice that should always be avoided. Do not use from tkinter import * , use import tkinter , import tkinter as tk or from tkinter import Button, Label....

  • If you give a name to an instance of a widget (button, label, etc.) it is assumed that it is to use that name to access widget properties. In this case, separate the method pack , grid , etc from the instance. If you do:

    txtBarras=Entry(ventData,textvariable=n_generadores).grid(row=2,column=0)
    

    txtBarras is not an instance of Entry but it is None , the return of method grid . This means that, logically, you can not access the Entry or its properties, for example txtBarras.get() will give an error. For those you must do:

    txtBarras=Entry(ventData,textvariable=n_generadores)
    txtBarras.grid(row=2,column=0)
    

    If you are not going to need to access the instance then you do not create a lot of variables that will contain all None , you simply do:

    Entry(ventData,textvariable=n_generadores).grid(row=2,column=0)
    

The functional code would look like this:

import numpy as np
import tkinter as tk


matriz_v = None
Barras = []


def BaseD():
    #Es necesario usar global si vas a usar matriz_v fuera de esta funcion
    global  matriz_v

    m = n_generadores.get()
    matriz_v = np.zeros((m,m))

    for i in range(0,m):
        matriz_v[i,i] = Barras[i][0].get()   
    print(matriz_v)  

#crear las tablas   
def Tabla():

    #TABLAS
    ventData.geometry("1500x600+0+0")
    lbld_generadores = tk.Label(ventData, text="Datos de los generadores: ", font=14)
    lbld_generadores.grid(row=4, column=0)

    #NUMERO DE LA BARRA DONDE SE UBICARA EL GENERADOR
    n_Barra = ["Barra"]
    #Creacion de la fila de etiquetas BARRA
    for i in range(len(n_Barra)):
        tk.Label(ventData, text=n_Barra[i], bg="LightSteelBlue2", font=(12), relief=tk.GROOVE, padx=10, pady=5).grid(row=4,column=i+1)

    #crear las filas de acuerdo al numero de barras ingresadas
    filasB = n_generadores.get()

    for i in range(filasB):
        Barras.append([0]*len(n_Barra))
        for j in range(len(n_Barra)):
            Barras[i][j]=("B{}{}".format(i, j))
            Barras[i][j] = tk.DoubleVar()
            tk.Entry(ventData, textvariable=Barras[i][j], width=16, bg="beige").grid(row=i+5, column=j+1)


#CALCULAR
    btnCreaBD = tk.Button(ventData,text="Calcular",font=(14),command=BaseD,padx=10,pady=1)
    btnCreaBD.grid(row=filasB+7,column=1)
    lblVacia = tk.Label(ventData,text="")
    lblVacia.grid(row=filasB+8,column=2)

#Ventana inicial
ventData=tk.Tk()
ventData.geometry("800x400+0+0")
ventData.title("DESPACHO ECONOMICO")

lbln_generadores=tk.Label(ventData,text="Número de Generadores: ",font=(16))
lbln_generadores.grid(row=1,column=0)

#Parametro de entrada - numero de generadores
n_generadores=tk.IntVar()

txtBarras=tk.Entry(ventData,textvariable=n_generadores)
txtBarras.grid(row=2,column=0)

#Boton Aceptar
btnn_generadores=tk.Button(ventData,text="Aceptar",font=(14),command=Tabla,padx=10,pady=1)
btnn_generadores.grid(row=2,column=1)

#Insertar fila vacia
lblVacia=tk.Label(ventData,text="")
lblVacia.grid(row=2,column=2)

ventData.mainloop() 

Note that it is not necessary to use global when modifying mutable objects such as lists or arrays of NumPy. If you overwrite the variable with another object or it is immutable ( int , float , str , etc) if you need to use global .

However, I would recommend using object-oriented programming (classes). You avoid using global variables (which should be avoided where possible ), the code will be much more organized, in the end you will have to write less code, and especially the Gui It will be much more flexible, extensible and reusable.

    
answered by 10.06.2017 в 23:44