Python, 'tkinter' has no attribute 'get' - python

I'm trying to print the value xf_in which is entered in the GUI.
However, I get the following error message when i press the run button:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\My_Name\Anaconda3\lib\tkinter\__init__.py", line 1699, in __call__
return self.func(*args)
File "C:/Users/My_Name/Python Scripts/test/gui.py", line 6, in EP
xf_In = tk.get(e_xf)
AttributeError: module 'tkinter' has no attribute 'get'
I've tried to find the source of the error online but to no avail.
Thanks in advance for any help
My code is as follows:
import tkinter as tk
from PIL import ImageTk as imtk
from PIL import Image as im
def EP(): # Enter inputs from values typed in
xf_In = tk.get(e_xf)
print(xf_In)
root = tk.Tk()
l_xf = tk.Label(root, text="xA of Feed").grid(row=0)
e_xf = tk.Entry(root).grid(row=0, column=1)
run = tk.Button(root, text="Run", command=EP).grid(row=8, column=0, columnspan = 2)
img = imtk.PhotoImage(im.open("x.png"))
panel = tk.Label(root, image = img).grid(row = 0, column = 2, rowspan = 7)
root.mainloop()

As the error message indicates, the tk module does not have a function named get. It might have plenty of classes whose instances have a get method, but you can't access them the way you're doing.
If you're trying to get the contents of the Entry, you should assign it to a name, and call get on that instead:
def EP(): # Enter inputs from values typed in
xf_In = e_xf.get(e_xf)
print(xf_In)
#...
e_xf = tk.Entry(root)
e_xf.grid(row=0, column=1)
Note that this assignment is different from doing e_xf = tk.Entry(root).grid(row=0, column=1). If you do that, then e_xf will be bound to the return value of grid, rather than the Entry instance. grid returns None, so trying to call get on that would only give you an AttributeError. Related reading: Why do my Tkinter widgets get stored as None?

Related

How to avoid tkinter's IntVar.get() raising TclError on blank strings

I've got an Entry tied to an IntVar, but calling my_int_var.get() throws an exception that seems to complain that the variable is an empty string. I only expect integers to be input by the user in that field.
Is there a better solution besides catching TclError?
Here's the traceback I'm trying to avoid:
|| Traceback (most recent call last):
|| File "Python36-32\lib\tkinter\__init__.py", line 1699, in __call__
|| return self.func(*args)
|| File "/gui.py", line 172, in callback
|| print(f"Value is now: {my_int_var.get()}")
|| File "Python36-32\lib\tkinter\__init__.py", line 507, in get
|| return int(self._tk.getdouble(value))
|| _tkinter.TclError: expected floating-point number but got ""
This is triggered on a callback tied to the my_int_var's .trace() call. The exception is thrown when you erase the content of the Entry by selecting all the text with a mouse and hitting backspace, leading to a blank value.
Here's some code you can run yourself to reproduce the issue, without having to use the mouse:
import tkinter as tk
root = tk.Tk()
my_int_var = tk.IntVar()
entry = tk.Entry(textvariable=my_int_var)
entry.delete(0, tk.END)
my_int_var.get() #throws TclError
You are receiving the error because the variable is empty. You can set the initial value to 0 to prevent this error using:
var.set(0)
And also, you don't need to delete the data from the entry, because when an entry is created, it is empty. So remove line:
entry.delete(0, tk.END)
Here is a code:
import tkinter as tk
root = tk.Tk()
var = tk.IntVar()
entry = tk.Entry(textvariable=var)
var.set(0) #<-- Set the value to 0
var.get() #<-- Working
Edit:
You can use the try/except statement. Here is a working of the statements:
import tkinter as tk
root = tk.Tk()
var = tk.IntVar()
entry = tk.Entry(textvariable=var)
entry.pack()
var.set(0) #<-- Set the value to 0
def _get():
try:var.get()
except:var.set(0)
tk.Button(text="Press",command=_get).pack()
root.mainloop()
#var.get() #<-- Working
When you press the button, if the entry is empty, its value will be set to 0.

python3 with tkinter: call widget from a function

I'm having a problem with this code:
from tkinter import *
class app:
def create(arrSettings):
proot = Toplevel()
proot.title("Settings")
m = Frame(proot).pack() #Some Frames so I can arrange them how I'd like to
mcan = Canvas(proot)
mcan.pack(fill="both", side="left")
x = Frame(proot).pack()
xcan = Canvas(proot)
xcan.pack(fill="both", expand="yes", side="left")
win_0 = Frame(xcan)
lbl_0 = Label(win_0, text="Option0").pack()
txt_0 = Text(win_0).pack()
win_0.pack()
win_1 = Frame(xcan)
lbl_1 = Label(win_1, text="Option1").pack()
txt_1 = Text(win_1).pack()
win_1.pack()
btn_menu0 = Button(mcan, text="Menu0", command=app.func_btn_menu0).pack()
btn_menu1 = Button(mcan, text="Menu1", command=app.func_btn_menu1).pack()
def func_btn_menu0():
lbl_0.config(text="foo") # <-- Problem
txt_0.insert("end", "bar") # <-- Problem
def func_btn_menu1():
pass
(I left the code for the design(bg, border, ...) out)
This is another window which will be started by the main one.
It shows some buttons on the left and some labels and textboxes on the right.
Whenever a button on the left has been pushed the text of the labels should be changed.
That's the problem: When I push a button I get this error and the text won't be changed:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.4/tkinter/__init__.py", line 1536, in __call__
return self.func(*args)
File "/[...]/program.py", line 27, in colormain
lbl_0.config(text="Background")
NameError: name 'lbl_0' is not defined
I don't really understand why this gives me an error so I'd like to ask you.
This code is being started from the main window with the code:
program.app.create(arrSettings) #arrSettings is an array in which some colors for the design are
Thanks in advance.
Do not declare and pack in the same line
Return of this peice of code is None
Label(win_0, text="Option0").pack()
whereas, this returns an object of Label class
Label(win_0, text="Option0")
so use:-
lbl_0 = Label(win_0, text="Option0")
lbl_0.pack()
instead of
lbl_0 = Label(win_0, text="Option0").pack()
Also use self object as argument to functions. Check that the variables are in scope wherever you are using it.
This should help you get through this error...

My function is confused about whether or not it wants a second argument (python, matplotlib)

I'm writing a (should be) simple program in Python using Tkinter and Matplotlib to control a machine. It's my first Python program, so apologies for any egregious non-conventions, and I welcome all feedback. Also, sorry for the large code block.
I'm trying to have a main page for controls, and a secondary page that shows up with a graph while the machine is performing a run. I've managed to get the second page to show up and go away properly, and show the graph. However, every time it adds a point to the graph, it yells at me about
>
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.4/tkinter/__init__.py", line 1536, in __call__
return self.func(*args)
File "/usr/lib/python3.4/tkinter/__init__.py", line 585, in callit
func(*args)
TypeError: graph_animate() missing 1 required positional argument: 'i'
So I removed the ", i" argument from my graph function so it only takes (self), then it yelled at me in a different manner:
>
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/matplotlib/figure.py", line 381, in show
manager = getattr(self.canvas, 'manager')
AttributeError: 'FigureCanvasTkAgg' object has no attribute 'manager
followed by a bunch of locations within files and modules, ending with:
>
....File "/usr/local/lib/python3.4/dist-packages/matplotlib/animation.py", line 1212, in _draw_frame
self._drawn_artists = self._func(framedata, *self._args)
TypeError: graph_animate() takes 1 positional argument but 2 were given
I'm not very familiar with troubleshooting in Python, but it seems like a catch-22 type deal where I specify another argument and it says I don't have it, so I take it out and it says it's got too many. I spent a fair amount of time trying to figure out what was going on, and how constructors are specified in tkinter, but I still couldn't fix the error.
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.animation as animation
from matplotlib import style
import datetime
import time
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import tkinter as tk
from tkinter import ttk, StringVar
import urllib
import json
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
f = Figure()
a = f.add_subplot(111)
gsFurnaceTemp = 0
plottime = []
plottemp = []
class BrokeApp:
global gsFurnaceTemp
def __init__(self, parent):
self.myParent=parent
self.root=parent
self.myContainer1=tk.Frame(parent)
self.myContainer1.pack()
label = tk.Label(self.myContainer1, text = "My Broken App")
label.grid(columnspan=4)
buttonStart=tk.Button(self.myContainer1, text="Start Run",
bg='green', height=3, width=20,
command = self.btnStartClick)
buttonStart.grid(row=7, column=1)
self.ChillerLabelText = StringVar()
self.ChillerLabelText.set(gsFurnaceTemp)
lblChillerTemp = tk.Label(self.myContainer1, textvariable=self.ChillerLabelText)
lblChillerTemp.grid(row=100, column=100)
self.getDataTimer()
def btnStartClick(self):
self.newWindow=tk.Toplevel(self.myParent)
self.app=GraphPage(self.newWindow)
def getDataTimer(self):
gsFurnaceTemp=open("TempTxt.txt", "r").read()
self.ChillerLabelText.set(str(gsFurnaceTemp))
self.root.after(1000, self.getDataTimer)
class GraphPage:
global gsFurnaceTemp
def __init__(self, parent):
self.myParent=parent
self.root=parent
self.master=parent
self.plottempz = []
self.plottimez = []
self.fz = Figure()
self.az = self.fz.add_subplot(111)
self.myContainer1=tk.Frame(parent)
self.myContainer1.pack()
label = tk.Label(self.myContainer1, text = "Temp Graph")
label.pack(pady=10, padx=10)
btnStartPage = ttk.Button(self.myContainer1, text="Back to Main Page",
command = self.close_Window)
btnStartPage.pack(padx = 10, pady = 10)
canvas = FigureCanvasTkAgg(self.fz, self.myContainer1)
canvas.show()
canvas.get_tk_widget().pack()
plottemp= []
plottime= []
ani = animation.FuncAnimation(self.fz, self.graph_animate, interval=1000)
self.fz.show()
def graph_animate(self, i): #THIS IS THE LOCATION WHERE I REMOVE AND
#INSERT THE ", i" WHICH HAS BEEN GIVING ME TROUBLES
gsFurnaceTemp=open("TempTxt.txt", "r").read()
plottemp.append(gsFurnaceTemp)
self.az.clear()
self.az.plot(plottemp)
self.root.after(1000, self.graph_animate)
gsFurnaceTemp=open("TempTxt.txt", "r").read()
def close_Window(self):
self.master.destroy()
def main():
root = tk.Tk()
app = BrokeApp(root)
root.geometry("800x600")
root.mainloop()
if __name__ == "__main__":
main()
Also, sorry if any of this code is redundant or any of my declared variables are unused. My brain is fairly fried just from figuring out how to condense it into a sufficiently short, yet compilable chunk from the larger program.
Steeeeeve
That i must be defined, you can check how 'frames' work in FuncAnimation. I will suggest you to read the documentation about matplotlib.animation.FuncAnimation.

How to resolve this error in Python?

I know this will be marked as a duplicate post as there were some questions about this error. I've gone through those, but got no idea how to resolve it. Please help me. Here is the error message.
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__
return self.func(*args)
File "iptrace.py", line 21, in mbt
tkMessageBox.showinfo(tget, tget+" lives in "+jd["city"]+", "+jd["region"]+" "+jd["country"])
TypeError: cannot concatenate 'str' and 'NoneType' objects
Here is the code:
from Tkinter import *
import tkMessageBox
import json
import urllib
import sys
def wmi():
uip = urllib.urlopen("http://www.networksecuritytoolkit.org/nst/tools/ip.php").read()
tkMessageBox.showinfo("Whats my IP", "Your IP is "+uip)
def mbt():
global ew1
tget = ew1.get().strip()
jd = json.load(urllib.urlopen("http://ipinfo.io/"+tget+"/geo"))
if tget == "":
tkMessageBox.showerror(tget, "Type a IP Please")
else:
tkMessageBox.showinfo(tget, tget+" lives in "+jd["city"]+", "+jd["region"]+" "+jd["country"])
if __name__ == "__main__":
root = Tk()
root.title("-|IP2Location|-")
textFrame = Frame(root)
entryLabel = Label(textFrame)
entryLabel["text"] = "IP :"
entryLabel.pack(side=LEFT)
ew1 = Entry(textFrame)
ew1["width"] = 24
ew1.pack(side=LEFT)
textFrame.pack()
bmi = Button(root, text="Whats my IP", command=wmi)
bmi.pack()
bs = Button(root, text="Submit", command=mbt)
bs.pack()
def enterPress(event):
mbt()
root.bind("<Return>", enterPress)
def enterPress(event):
exit()
sys.exit(0)
root.bind("<Escape>", enterPress)
root.mainloop()
The error, as stated in the Traceback is located in:
else:
tkMessageBox.showinfo(tget, tget+" lives in \
"+jd["city"]+", "+jd["region"]+" "+jd["country"])
So what's causing the problem is you're using the + sign for two different types, one being a string and the other NoneType (i.e. has no value).
So what you'll need to do is change the predefined variables to strings using str(var) that you're trying to concatenate within that statement. Only then it'll run without issue.

AttributeError: 'NoneType' object has no attribute 'grid_remove'

I have only done a little work with Tkinter and I enjoy using it but as with any type programing it takes time to learn. I am trying to create a simple To do list that will eventually be saved on a file. But i can't get the button in line 17 to be removed and the on the next line be replace in a different position.
from tkinter import *
import time
root = Tk()
root.geometry("300x300")
root.title("Programs")
global TDrow
TDrow = 2
def tdTaskAdd():
global TDrow
global tdEnter
TDrow = int(TDrow+1)
s = tdEntry.get()
label = Label(ToDoFrame,text=s).grid(row=TDrow,column=1)
tdEntry.grid(row=TDrow+1,column=1)
tdEnter.grid_remove()
tdEnter = Button(ToDoFrame,text="AddTask",command=tdTaskAdd).grid(row=TDrow+2,column=1)
ToDoFrame = Frame()
ToDoFrame.place(x=0,y=10)
tdTitle = Label(ToDoFrame,text="To Do List:").grid(row=TDrow-1,column=1)
tdEntry= Entry(ToDoFrame)
tdEntry.grid(row=TDrow+1,column=1)
tdEntry.insert(0, "Enter a new task")
global tdEnter
tdEnter = Button(ToDoFrame,text="Add Task",command=tdTaskAdd).grid(row=TDrow+2,column=1)
mainloop()
I keep getting an error when running this saying that:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__
return self.func(*args)
File "C:\Users\Eddy\Desktop\pythonStartup.py", line 17, in tdTaskAdd
tdEnter.grid_remove()
AttributeError: 'NoneType' object has no attribute 'grid_remove'
The problem is this line:
tdEnter = Button(ToDoFrame,text="Add Task",command=tdTaskAdd).grid(row=TDrow+2,column=1)
This way, tdEnter is not the Button, but the return value of grid, i.e. None.
Try this instead:
tdEnter = Button(ToDoFrame,text="Add Task",command=tdTaskAdd)
tdEnter.grid(row=TDrow+2,column=1)
Same for label and when you create a new button in your tdAddTask function.
BTW, no need to add a new button each time, just call it's grid method to repositon it.

Categories