tkinter AttributeError: 'NoneType' object has no attribute 'get'

Iniciado por PUAROT, 5 Octubre 2016, 23:01 PM

0 Miembros y 1 Visitante están viendo este tema.

PUAROT

Tengo un problema que no soy capaz de resolver por que no lo entiendo.

Cuando intento utilizar atributos de un objeto que según la documentación de tkinter posee dicho objeto me sale el error AttributeError: 'NoneType' object has no attribute

Me ha pasado intentado poner el foco en un Entry por ejemplo y de lo unico que me he dado cuenta después de buscar por internet ejemplos de utilización, es que cuando sitúas un elemento en una posición con place(x,y) no me funciona, sin embargo al utilizar el .pack() si No lo entiendo, yo quiero diseñar la aplicación diciendo exactamente donde quiero las cosas.

Como no se si me he explicado bien, aquí pongo un ejemplo muy sencillo del problema :
 
Este código funciona:

from tkinter import *

root = Tk()
root.geometry("640x490")

label = Label(root, text='Entrada').place(x=20,y=210)
entry = Entry(root)
button = Button(root, text="Presioname")
button.pack()
entry.pack()

def funcion():
    print (entry.get())
   
button.config(command=funcion)

root.mainloop()


y este no:

from tkinter import *

root = Tk()
root.geometry("640x490")

label = Label(root, text='Entrada').place(x=20,y=210)
entry = Entry(root).place(x=80,y=210)
button = Button(root, text="Presioname")
button.pack()

def funcion():
    print (entry.get())
   
button.config(command=funcion)

root.mainloop()

tincopasan

modifiqué apenas tu código que no anda:
Código (python) [Seleccionar]

from tkinter import *

root = Tk()
root.geometry("640x490")
texto=StringVar()  #hay que iniciar una variable para el texto en este caso
label = Label(root, text='Entrada').place(x=20,y=210)
entry = Entry(root,textvariable=texto).place(x=80,y=210)  #uno(enlazo) esa variable con el entry
button = Button(root, text="Presioname")
button.pack()

def funcion():
    print (texto.get())   #ahora obtengo lo que tiene la variable texto

button.config(command=funcion)

root.mainloop()


perdón pero no has buscado lo suficiente sobre get y set de los entry.

PUAROT

Ante todo muchas gracias por contestar !!!c

Tienes razón en que no he buscado mucho sobre get y set , pero es por que no se exactamente como buscar para el problema que tengo, me explico mejor...

Mi problema no es que no funcionara el código que has arreglado con explicación incluida, (cosa que agradezco) Este era solo un ejemplo ya que el problema no es get o set, si no que no me deja aplicar esos y otros atributos .
En el código que estoy haciendo donde me surge el problema, tengo un entry con su variable Stringvar asociada y me funciona el get perfectamente,,pero si intento aplicarle el focus() osea que al abrir la aplicación este el foco sobre esa caja de texto me da el mismo error, también tengo un botón al cual he intentado aplicar un bind para asociuar una tecla a dicho botón y también me da el m mismo error

En este ejemplo se ha solucionado poniendo un Strinvar asociado al Entry para usar un get, pero que pasa si le intento poner el foco a la caja de texto ? da error, lo mismo que si lo intento al botón (usando place)

Si en tu código aplico button.focus() funciona perfectamente, pero si ese boton en lugar de estar situado con el button.pack() lo situas con .place(x=20,y=50) ya no funciona el focus y da el error que comento...

Es un poco engorroso de explicar y no se si me he explicado bien cual es el problema, lo que esta claro es que no se por donde buscar.

Gracias otra vez y si no me he explicado bien pongo otro ejemplo


tincopasan

#3
a ver si es algo así aplicado a este mismo ejemplo:
Código (python) [Seleccionar]

from tkinter import *

root = Tk()
root.geometry("640x490")
texto=StringVar()
label = Label(root, text='Entrada').place(x=20,y=210)
entrada= Entry(root,textvariable=texto)  # acá esta la diferencia en la declaración! creo la   instancia solamente, así después puedo aplicarle los métodos, place , focus, etc.
entrada.place(x=80,y=210)
entrada.focus()
button = Button(root, text="Presioname")
button.pack()

def funcion():
   print (texto.get())

button.config(command=funcion)

root.mainloop()



dicho sea de paso, tk sirve para empezar, pero cuando necesites algo más profesional te recomiendo pyqt y si vas a aprender de 0 empezá por la versión 5 directamente.

PUAROT

Pues si, se soluciona!!! no se me hubiera ocurrido que así se solucionase, es muy curioso el problema y la solución, o al menos a mi me lo parece :-D

Lo que aprende uno por aquí jeje Muchas gracias !!!!

Respecto a lo de pyqt lo he pensado y mirado, de hecho tengo guardados en favoritos algo de documentación para cuando pueda empezar... tengo Mac con Maverics y no me deja instalarlo, tengo pendiente hacer copia de seguridad y actualizar el SO, entonces empezaré a mirarlo.
Ya que estamos, una pregunta mas  una vez desarrolle alguna aplicación con pyqt y python, para ejecutar esa aplicación en un pc tiene que estar instalado python y pyqt? hay formas de crear un ejecutable para ejecutar dicha aplicación en cualquier pc?  conozco py2exe, pero no se si valdría...


tincopasan

si se puede compilar un exe, tanto con py2exe como con cx_freeze para sistemas windows, con repecto a otros SO no tengo la menor idea ya que no los uso.

PUAROT

Muchas gracias !! como ya comenté, gracias a su ayuda terminé la aplicación (básica, pero que me resuelve una necesidad:-) ) ademas de aprender cosas nuevas, esta aplicación me ha servido para aprender bastante, lo cual significa que tengo que seguir escribiendo código para seguir aprendiendo.

No se si crear un hilo nuevo para esto, pero tengo otra cuestion, espero no ser muy pesado

Respecto a py2exe, ya lo había utilizado en mis primeros códigos escritos para interactuar por la consola, sin mayores problemas, pero al tener una interface gráfica con tkinter no soy capaz de generar un exe sin añadidos, osea, que este todo en el exe

Me explico, o eso intentaré...

con un archivo setup.py como este :
from distutils.core import setup
from tkinter import *
import py2exe
import sys
import os

sys.argv.append('py2exe')

setup(name="Prueba",
version="2.0",
description="prueba de py2exe.",
author="",
author_email="",
url="",
license="libre de uso con reconocimiento",
scripts=["prueba.py"],
console=[{"script": "prueba.py", "icon_resources": [(1, "icon.ico")]}],
options={"py2exe": {"bundle_files": 1}},
windows=[{'script':"prueba.py"}],


me dice :
running py2exe
running build_scripts
copying prueba.py -> build\scripts-3.4

3 missing Modules
------------------
? readline imported from cmd, code, pdb
? win32api imported from platform
? win32con imported from platform
OOPS: tkinter 2

si pongo el "bundle_files" a 2 en lugar de uno, me genera carpetas y archivos mas el exe, pero el exe no funciona como debería, varias funciones de la aplicación no funcionan

He estado buscando por internet, y lo que he entendido es que debe existir una forma de crear un solo archivo pero yo no doy con ella y que con el "bundle_files" a 2 tendrioa yo que copiar ciertos archivos de los que me genera a sus carpetas correspondientes o eso me parece interpretar
Si la única opción es ponerlo a 2 y que genere todos los archivos, ¿hay forma de automatizar que esos archivos se copien en el lugar adecuado?
Hay mas opciones?

Gracias otra vez

PUAROT

He conseguido crear un exe (con sus añadidos) que funcione con cx_freeze y el siguiente setup.py
import sys
from cx_Freeze import setup, Executable
base = None
if sys.platform == 'win32':
    base = 'Win32GUI'
options = {
    'build_exe': {
        'compressed': False,
        'includes': ['Funciones_conversion']
    }
}


executables = [
    Executable('archivo.py', base=base)
]

setup(name='archivo',
      version='2',
      description='Prueba.',
      executables=executables,
      options=options
      )


Ahora me falta probar con py2exe a ver que tal va, ya que he empeado a enterarme de como va  cx_freeze
Uno de los problemas para que no funcionara bien, he descubierto que es al importar el modulo Tkinter, yo tenia:
from tkinter import*
y he tenido que hacer algunos mas del estilo :
from tkinter import filesistem
para que funcione el codigo completo.
Con esto ya tengo una carpeta con todos sus archivos añadidos en la que está el ejecutable y al cambiar la carpeta de ordenador, FUNVIONA! !!

Aun así me gustaría saber si cabe la posibilidad de crear un archivo único.