How do I call an entry on tkinter? [duplicate] - python

This question already has answers here:
Tkinter: AttributeError: NoneType object has no attribute <attribute name>
(4 answers)
Closed 2 years ago.
I'm new to Python and I'm struggling to figure out what's wrong with my code.
import tkinter as tk
r = tk.Tk()
r.title('PROJECT')
def file_entry():
global ent
tk.Label(r, text = "ENTRY").grid(row = 2)
ent = tk.Entry(r).grid(row = 2, column = 1)
b_ent = tk.Button(r, text="OK", width = 5, command = print_input).grid(row = 2, column = 2)
def print_input():
print(ent.get())
l = tk.Label(r, text="OPTION 1 OR 2?").grid(row = 0)
b = tk.Button(r, text='1', width=25, command=file_entry).grid(row = 1,column = 0)
b2 = tk.Button(r, text='2', width=25, command=r.destroy).grid(row = 1,column = 1)
r.mainloop()
I'm trying to call "ent", but every time I run it, it would give me an error for it being a NoneType.
Like I said, I'm new to Python, and this is a school project, it would really be helpful if someone could explain what the problem is, as simply as possible.
Thanks!

It appears that chaining the grid to the entry widget is not acceptable.
If you put it on a separate line, the ent variable get properly assigned and get the inputted value as opposed to not working and being assigned None.
Try this:
def file_entry():
global ent
tk.Label(r, text="ENTRY").grid(row=2)
ent = tk.Entry(r)
ent.grid(row=2, column=1)
b_ent = tk.Button(r, text="OK", width=5, command=print_input).grid(row=2, column=2)

Related

Why binding a key to Entry widget doesn't work? [duplicate]

This question already has an answer here:
Basic query regarding bindtags in tkinter
(1 answer)
Closed 10 months ago.
HI guys i'm trying to simply create a text space that replaces the letters or any input into asterisks just like happen with the regular passwords. But why if i bind any key to the function "text" if i press any key the first input is empty? Becuase if i type "m" when in the function i print(e.get()) the output is empty in the console? Why it ignores the input and how to simply show the asterisk in the text area and bind the normal password to the variable "a" just like in my code? With e.delete and e.insert i simply cut the last character and replace it with asterisk here is my code
from tkinter import *
a = ""
window = Tk()
def entra():
global a
if a == "cgf":
print ("a")
else:
print("noo")
def text (event):
global a
a = a + e.get()
print(e.get())
e.delete(len(e.get()) - 1)
e.insert(END, "*")
e = Entry(window, borderwidth=3, width=50, bg="white", fg="black")
e.place(x=100, y=35)
e.bind("<Key>", text)
bottone_entra = Button (window, text = "Entra", borderwidth=2.5,command = entra)
bottone_entra.place (x=100, y=65)
etichetta = Label(window, text = "PASSWORD", bg = "#2B2B2B", fg = "white")
etichetta.place(x=97.5, y=10)
window.geometry ("500x500")
window.title ("Password")
window.configure(bg = "#2B2B2B")
window.mainloop()
You don't have to manually build a logic for it, tkinter luckily already provides it. You just have to set an extra option to the entry widget, show='*':
e = Entry(window, borderwidth=3, width=50, bg="white", fg="black", show='*')
There are many reasons as to why you should avoid building/using this logic of your own, to begin with, once you do get(), you will only get **** and not whatever the text originally was.

How do i call a function everytime my entry is updated [duplicate]

I'm trying to make a simple temperature conversion calculator in python. What I want to do is to be able to type in a number, and have the other side automatically update, without having to push a button. Right now I can only get it to work in one direction. I can either code it so that it can go from F to C, or C to F. But not either way.
Obviously after is not the way to go. I need some kind of onUpdate or something. TIA!
import Tkinter as tk
root = tk.Tk()
temp_f_number = tk.DoubleVar()
temp_c_number = tk.DoubleVar()
tk.Label(root, text="F").grid(row=0, column=0)
tk.Label(root, text="C").grid(row=0, column=1)
temp_f = tk.Entry(root, textvariable=temp_f_number)
temp_c = tk.Entry(root, textvariable=temp_c_number)
temp_f.grid(row=1, column=0)
temp_c.grid(row=1, column=1)
def update():
temp_f_float = float(temp_f.get())
temp_c_float = float(temp_c.get())
new_temp_c = round((temp_f_float - 32) * (5 / float(9)), 2)
new_temp_f = round((temp_c_float * (9 / float(5)) + 32), 2)
temp_c.delete(0, tk.END)
temp_c.insert(0, new_temp_c)
temp_f.delete(0, tk.END)
temp_f.insert(0, new_temp_f)
root.after(2000, update)
root.after(1, update)
root.mainloop()
What you are looking for is variable trace() method. E.g.:
def callback(*args):
print "variable changed!"
var = DoubleVar()
var.trace("w", callback)
Attach trace callbacks for each of your DoubleVar, for temp_f_number one to update the temp_c_number value and vice versa. You'll likely also need to disable one callback function while inside another one, to avoid recursive update cycle.
Another note - do not edit the Entry fields. Instead, use variables' set() method. Entry fields will be updated automatically.
So, complete code could look like this:
import Tkinter as tk
root = tk.Tk()
temp_f_number = tk.DoubleVar()
temp_c_number = tk.DoubleVar()
tk.Label(root, text="F").grid(row=0, column=0)
tk.Label(root, text="C").grid(row=0, column=1)
temp_f = tk.Entry(root, textvariable=temp_f_number)
temp_c = tk.Entry(root, textvariable=temp_c_number)
temp_f.grid(row=1, column=0)
temp_c.grid(row=1, column=1)
update_in_progress = False
def update_c(*args):
global update_in_progress
if update_in_progress: return
try:
temp_f_float = temp_f_number.get()
except ValueError:
return
new_temp_c = round((temp_f_float - 32) * 5 / 9, 2)
update_in_progress = True
temp_c_number.set(new_temp_c)
update_in_progress = False
def update_f(*args):
global update_in_progress
if update_in_progress: return
try:
temp_c_float = temp_c_number.get()
except ValueError:
return
new_temp_f = round(temp_c_float * 9 / 5 + 32, 2)
update_in_progress = True
temp_f_number.set(new_temp_f)
update_in_progress = False
temp_f_number.trace("w", update_c)
temp_c_number.trace("w", update_f)
root.mainloop()
.trace is soon to be deprecated, use .trace_add instead:
var = tk.StringVar()
var.trace_add('write', callback)
Same functionality, but you must pass write or read instead of w or r.

Python scroller for input

I wanted to start a new project with python, so i saw this so it looked cool so i wanted to give it a try, but i dont know how to make that scroller, all i found online was ways to make it scroll through text and documents, but not to control input, could someone help me make something like this?
and is there a way to make it display the number of characters above the scroller?
this is what i got online, i dont know if its the same thing as what i want
scrollbar1 = Scrollbar(master1, bg="green")
scrollbar1.pack( side = RIGHT, fill = Y )
You are looking for Scale widget . Please check this snippet and also please refer https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/scale.html for more details.
from tkinter import *
root = Tk()
root.geometry("100x100")
v1 = DoubleVar()
s1 = Scale( root, variable = v1,from_ = 1, to = 100,orient = HORIZONTAL)
l3 = Label(root, text = "Horizontal Scaler")
l1 = Label(root)
s1.pack(anchor = CENTER)
l3.pack()
l1.pack()
root.mainloop()
Edit
If you want the scale value dynamically on moving the pointer of scale and without triggering any button then please check this snippet along with screenshot.
from tkinter import *
def get_value(val):
scale_val = "Scale value= " + str(val)
label.config(text = scale_val)
root = Tk()
root.geometry("100x150")
v1 = DoubleVar()
s1 = Scale( root, variable = v1,from_ = 1, to = 100,orient = HORIZONTAL, command=get_value)
l3 = Label(root, text = "Horizontal Scaler")
l1 = Label(root)
s1.pack(anchor = CENTER)
l3.pack()
l1.pack()
label = Label(root)
label.pack()
root.mainloop()

Tkinter Entry Field Capture AttributeError: [duplicate]

This question already has answers here:
Tkinter: AttributeError: NoneType object has no attribute <attribute name>
(4 answers)
Closed 5 years ago.
I want to capture the data in the entry field from the second window defined under output. When I click submit get the following message: AttributeError: 'NoneType object has no attribute 'get'.
I feel like this should be an easy fix and do not understand why can't I capture the data from the entry field?
from tkinter import *
import xlsxwriter
class MyFirstGUI:
def __init__ (self, master):
master.title("Main")
master.geometry("400x400+230+160")
button1 = Button(master, text="1", command= self.output).grid(row=0, column=0)
def output(self):
cw1= Toplevel(root)
cw1.title("cw1")
cw1.geometry("400x300+160+160")
self.b2 = Button(cw1, text="Submit",command = self.write_to_xlsx).grid(row=0, column=2)
self.l2 = Label(cw1, text="New Specimen").grid(row=0, column=0)
self.e2 = Entry(cw1).grid(row=0, column=1)
def write_to_xlsx(self):
workbook = xlsxwriter.Workbook('tkintertest19.xlsx')
worksheet = workbook.add_worksheet()
worksheet.write_string('C1', self.e2.get())
workbook.close()
root = Tk()
my_gui = MyFirstGUI(root)
root.mainloop()
What you need to do is split the line
self.l2 = Label(cw1, text="New Specimen").grid(row=0, column=0)
into
self.l2 = Label(cw1, text = "New Specimen")
self.l2.grid(row=0, column=0)
Non-intuitive as this may seem, the grid/pack/place functions return None, so the whole shebang (Label().grid()) returns None. The solution is simply to split it up so that you get the right thing when you use .get().

Python can't get the .get function to work [duplicate]

This question already has answers here:
Error when configuring tkinter widget: 'NoneType' object has no attribute
(2 answers)
Closed 6 years ago.
Lurked around the forums but can't seem to get the get() function to works, it keeps returning that it is not defined. Can somebody point out what I did wrong?
from Tkinter import *
the_window = Tk()
def button_pressed ():
content = entry.get()
if (content == '1'):
print 'lol'
else:
print 'boo'
entry = Entry(master=None, width = 8, bg='grey').grid(row=2, column = 2)
button = Button(master=None, height=1, width=6, text='Go!', command=button_pressed).grid(row=2, pady=5, column=3)
the_window.mainloop()
The grid method returns None. This assigns a None value to entry.
Instead, you want to assign that instance of Entry to entry and then modify the grid:
entry = Entry(master=None, width = 8, bg='grey')
entry.grid(row=2, column = 2)
entry = Entry(master=None, width = 8, bg='grey').grid(row=2, column = 2)
This will assign entry to the return value of the .grid() method, but .grid() does not return anything, so entry will be None.
You should instead write
entry = Entry(master=None, width=8, bg='grey')
entry.grid(row=2, column=2)
Do the same for all other widgets.

Categories

Resources