I have several entry boxes made with tk: Entry()
I need to put what the user enters into a variable, which I do as such (as I have found online):
window = Tk()
#make entry and turn it into stringvar
entry1string = tk.StringVar
entry_1 = Entry(window,textvariable=entry1string)
#retrieve it into a variable
retrieved = entry1string.get()
This gives the following error:
AttributeError: 'str' object has no attribute 'get'
How do I get the string/value entered into the entry box by the user into a variable? The code seems to be just how every example I've found is, I don't see why it's giving me that error.
Refer here to know about Entry widgets in Tkinter.
What you can do is create a button, on which upon clicking, the data entered in the Entry box will be retrieved.
...
entry1string = tk.StringVar()
entry_1 = Entry(window,textvariable=entry1string).pack()
def retrieveData():
#retrieve it into a variable
retrieved = entry1string.get()
#print the data
print(retrieved)
#Or output the data on the window in a Label :
Label(window, text=retrieved).pack()
button1 = Button(window, text="PRINT", command=retrieveData).pack()
There needs to be a function to call when the button is clicked. you can print the data in the command line or even output on the GUI window, that's your choice.
Read the documentation to know more.
Related
I am trying to make sure that a user types something into a tkinter Entry widget. Basically, if they leave the entry field blank, I want the program to display a popup telling them to enter a valid name. However, this code is not working. I think I am not checking if something has been entered correctly. My guess is that I made a mistake around the if statement in the code.
def get_name():
top = Toplevel(root)
label = Label(top, text="Please input your name.")
label.pack()
name = Entry(top)
if name == ""
messagebox.showinfo(title="Error", message="Please enter a valid name.")
else:
pass
name.pack()
import tkinter as tk
from tkinter import messagebox
root = tk.Tk()
root.geometry(‘100x100’)
user_entry_var = tk.StringVar()
def validate_user_entry() -> None:
entry = user_entry_var.get()
if entry == “”:
messagebox.showerror(‘Error’, ‘Enter a valid name’)
user_entry = tk.Entry(root, textvariable=user_entry_var).pack()
validate_button = tk.Button(root, text = ‘Check’, command = validate_user_entry).pack()
root.mainloop()
In your code, name is referring to the Entry widget, not the text. To access the text, you would need to use text variables, and use the get() function to access the entry. I’m not sure what you’re making, but hopefully the code above should help.
I have a GUI that uses a class that calls a function that provides a popup window.
The popup box has a button that gets a directory from the user using askdirectory() from tkinter.filedialog, a pair of radio buttons(RadioG, RadioY), and checkbox(state_checkbox) that I want to update the two different variables(driveletter and statevalue) . I've set the drive letter to "G:" and that value is held correctly, but doesn't update if I select the "Y:" Radio button. I have the IntVar.set(1), but that checkbox does not populate as checked and checking/unchecking it keeps the value at 1 and does not update it to 0 when unchecked.
Any advice on what I'm missing to keep my values from updating is appreciated.
relevant section of code below:
class preferences(Preferences):
def save_preferences(self):
# Used to reset the folder location desired by the user
self.prefdialog = tk.Tk()
self.prefdialog.title('Set Preferences')
self.driveletter = tk.StringVar()
self.driveletter.set("G:")
self.statevalue = tk.IntVar()
self.statevalue.set(1)
self.fpath = '\\Desktop'
self.RadioG = tk.Radiobutton(self.prefdialog, text="G:", variable=self.driveletter,
value="G:", command=lambda: print(self.driveletter.get()))
self.RadioG.grid(row=3,column=0,sticky=tk.W,pady=4)
self.RadioY = tk.Radiobutton(self.prefdialog, text="Y:", variable=self.driveletter,
value="Y:", command=lambda: print(self.driveletter.get()))
self.RadioY.grid(row=3,column=1,sticky=tk.W,pady=4)
self.state_checkbox = tk.Checkbutton(
self.prefdialog, text="Check to use state folders",
variable=self.statevalue, command=lambda: print(self.statevalue.get()))
self.state_checkbox.grid(row=4,column=0,sticky=tk.W,pady=4)
self.prefdialog.mainloop()
For posterity: Looks like my issue was using Tk() twice. Per Bryan since I'm trying to create a popup window, I should be calling Toplevel(), not a second instance of Tk(). I also definitely called mainloop() twice, once for my main window and once for this popup window.
I don't know why but .pack_forget() is not working. Here is the code.
def home():
home = Frame(root)
welcome = Label(home, text = 'Welcome!')
if btn.config('relief')[-1] == 'raised':
btn.config(relief="sunken")
home.pack()
welcome.pack()
else:
btn.config(relief="raised")
home.pack_forget()
welcome.pack_forget()
btn = Button(assignmentButtons, text = 'Home', borderwidth = 0, padx = 18, anchor = 'w', activebackground = '#4a4646', activeforeground = '#918787', relief = RAISED, cursor = 'hand2', command = home)
btn.config(width=25, height=2, bg = '#363333', fg = '#918787')
btn.pack(anchor = 'nw')
Your issue is one of scope. .pack_forget() is removing the home frame and the welcome label from view. But the widgets that are being forgotten were only just created and never .pack'ed in the first place!
Every time your btn is pressed, a new frame named home and a new label called welcome are created. If btn's relief value is "raised", then these widgets are packed. Otherwise, the freshly created, not yet packed widgets are forgotten (which does nothing because they are not yet visible). You are never actually referring to the already packed widgets. You need to pass a reference to the widgets that were packed in order to remove them.
One way to do this is to generate your tkinter code using a class with home and welcome as attributes of the instantiated class. Then you can reference them with self.home.pack_forget() and self.welcome.pack_forget().
See this link for an example using a class definition.
I believe the problem you are running into is that you have a function and a TK Frame named the same thing. Try to differentiate them and see if that helps. ie. You have "home" listed as both the function and the Frame attached to root
like in HTML tag attribute required=required
I want make an Entry widget mandatory, the user must enter data in it, otherwise don't proceed to next step.
How to do it with tkinter?
There is no attribute "required" in Tkinter, you need to write a function to check whether the user entered data in the entry or not. Then use this function as the command of the "Next" button.
import tkinter as tk
def next_step():
if mandatory_entry.get():
# the user entered data in the mandatory entry: proceed to next step
print("next step")
root.destroy()
else:
# the mandatory field is empty
print("mandatory data missing")
mandatory_entry.focus_set()
root = tk.Tk()
mandatory_entry = tk.Entry(root)
tk.Label(root, text="Data *").grid(row=0, column=0)
mandatory_entry.grid(row=0, column=1)
tk.Button(root, text='Next', command=next_step).grid(row=1, columnspan=2)
root.mainloop()
Without your own function its not possible
from tkinter import *
def check_empty() :
if entry.get():
pass #your function where you want to jump
else:
print(' input required')
mw=Tk()
Txt=Lable(mw, text='enter data').pack()
entry=Entry(mw, width=20).pack()
Btn=Button(mw, text='click', command=check_empty).pack()
mw.mainloop()
If you have single field then jump to a new function or class else
if multiple entry blocks then use pass if successfully written some data in the entry field
Remember above code will check multiple fields at the same time after clicking the button.
I built an interface where the user fills a hierarchical form. Past values are displayed in a ttk.Treeview.
I allow the user to edit previous values by clicking on the tree. The value gets filled on the form where it can be edited and overwriten.
The problem: the value I insert on the Entry widget is only displayed the next time the user clicks it, so that it is always 1 click lagging. Please run my sample code to get a better understanding. It gets confusing because if the user clicks a value and then another, it will display the previously clicked value.
It must have something to do with the event handling routine in tkinter, but I could not find and answer.
How can I get rid of this lag?
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
def cb_clique(event):
item = tree.selection()[0]
entry1.delete(0, "end")
entry1.insert(0, item)
entry1 = tk.Entry(root, width=15)
entry1.grid(row=1,column=1)
tree = ttk.Treeview(root)
tree.bind("<Button-1>", cb_clique)
tree["columns"]=("valor")
tree.column("valor", width=200 )
tree.heading("valor", text="Valor")
tree.grid(row=3, column = 1, columnspan = 4)
tree.insert("", "end", iid = "Will display position",text = "Click me",
values=("a","b"))
tree.insert("", "end", iid = "Use position to get info",
text = "Click me", values=("a","b"))
root.mainloop()
Looks like the <Button-1> event triggers before the window notices that the selection has changed, so selection() returns the thing that was selected before your click. Try changing the event binding to <<TreeViewSelect>>.
tree.bind("<<TreeviewSelect>>", cb_clique)