I have a tkinter entry box in python but I can't get the input from it into my code? - python

This is my code below :
from tkinter import *
login = Tk()
username_1 = Entry()
username_1.pack(side=TOP)
input_username = login.username_1.get("1.0", END)
username = input_username
loginInfo = {"user1": "blue", "user2": "yellow", "user3": "green"}
if username in loginInfo:
print('Username correct!')
login.mainloop()
This is my error:
'AttributeError: '_tkinter.tkapp' object has no attribute 'username_1'':

When you create widgets, you are creating children of the root window. However, these children are not attributes of the root window. Thus, login.username_1 is invalid, just as the error is telling you.
In this specific case, the widget is simply username_1 (eg: input_username = username_1.get("1.0", END)). However, even that won't work for the following reasons:
the get method of the entry doesn't take arguments. You need to do username_1.get().
you are calling get about one millisecond after the entry has been created, well before the user has a chance to enter anything.
With a GUI toolkit you can't think of your program running linearly from top to bottom. Instead, you set things up to initially appear, and then you need to write functions that respond to events such as key presses and button clicks. For example, you might want to create a button with the label "Login" that calls a function to check for valid credentials. It would be within that function that you call the get() method.

Can you please provide information about what your code is supposed to do?
If you just want to avoid this error - change line 6 for this:
input_username = username_1.get()

Related

TKinter. Tcl_AsyncDelete: cannot find async handler

I am running tkinter library in the Odoo15 for a specific purpose.
I have created a custom python interpreter to run python code inside odoo.
To handle user inputs i specially designed a concept and via tkinter i am taking inputs from user.
In a code there may be more than one inputs and so i need to open the window more than one time. for example taken one input, Entered, closed window and then repeat the same process till final user input.
So in that case, at some movement my server getting terminated with a runtime error:
Tcl_AsyncDelete: cannot find async handler
Aborted (core dumped)
can anyone guide me how can i resolve this please ?
import tkinter as tk
import gc
root=tk.Tk()
root.geometry('800x200+600+300')
name_var=tk.StringVar()
var_1 = ''
def submit():
name=name_var.get()
global %s
var_1 = name
root.destroy()
name_label = tk.Label(root, text = 'Enter value', font=('calibre',10, 'bold'))
name_entry = tk.Entry(root,textvariable = name_var, font=('calibre',10,'normal'))
sub_btn=tk.Button(root,text = 'Submit', command = submit)
name_label.grid(row=0,column=0)
name_entry.grid(row=0,column=1)
sub_btn.grid(row=2,column=1)
root.mainloop()
when there is a line like value = input("Enter value")
i am replacing that line with the above code to take user input.
Looking forward to hear on this .. thanks
Without a minimal reproducible example it is more of a guessing than an answer.
But due to your request, I'll try my best guess. The information how you code this section below, can be crucial.
In a code there may be more than one inputs
and so i need to open the window more than
one time. for example taken one input,
Entered, closed window and then repeat the
same process till final user input.
If you destroy the root window, the instance of tkinter.Tk() and you try to retrieve the users input (data located in tkinter) of the destroyed instance you could run into trouble. Instead of creating new instances of tkinter.Tk use tkinter.Toplevel. You could hide the root window in many ways. I.e with overrideredirect and transparency.
TL;DR
Make sure you use the same instance of tkinter.Tk() through out the whole session and or connect the new instance with your server and vice versa.
Hope it will work out for you, especially because I don't know about odoo.

Tkinter Auto-update button state

I'm building a very basic login system. I've almost completed it but I have one problem. I need to put a check in the 'register' button to be disabled untill it's entry meets some conditions. Something like this. Now, I'm aware that 'while loops' don't work in tkinter and why. This is just an example of what I'm trying to do! Any advice?
What you can do is create the register button, but set the state to disabled;
regbtn = ttk.Button(
root, text="Register",
command=do_register,
state=tk.DISABLED
)
Later, you can treat regbtn like a dictionary and modify the state:
regbtn["state"] = "enabled"
To know when to enable the button, you need to validate the entry field.
(For example, my resin-calculator program does input validation.)
But it short, it involves:
registering a validation function with the tk.TK object.
Setting the Entry widget to validate on a keypress.
For example, say we want to validate that an entry is a number.
To do that we create a function as shown below.
As a side-effect, this validation function enables/disables the register button depending on the validity of the data:
def is_number(data):
"""Validate the contents of an entry widget as a float."""
try:
float(data)
except ValueError:
regbtn["state"] = "disabled"
return False
regbtn["state"] = "enabled"
return True
This function receives the contents of the entry widget and needs to return if that data is valid.
So, first we register that validation command;
root = tk.TK()
vcmd = root.register(is_number)
Then, when creating the button, we set it to call the validation whenever a key is pressed;
re = ttk.Entry(
parent,
validate="key",
validatecommand=(vcmd, "%P")
)

receiving selected choice on Tkinter listbox

I'm trying to build a listbox using Tkinter and receive the selected option by clicking it.
import Tkinter as tk
from Tkinter import *
root = tk.Tk()
lst=Listbox(root, height=30, width=50)
lst.insert(1, "hy")
lst.insert(2, "hello")
lst.insert(3, "hey")
lst.pack()
sel = lst.curselection()
print sel
root.mainloop()
However, when I run the code it prints me an empty tuple before I pressed any choise.
Does someone know how to get the selected choise after I press one and not right after I run it?
Thanks a lot :)
You are getting the selection about a millisecond after creating the widget, well before the user has a chance to see the UI much less interact with it.
GUI programs are event based, meaning that things happen in response to events. Events are things like clicking buttons, inserting data into input widgets, and selecting items from listboxes.
You need to do one of two things: create a button or other widget which will get the selected item, or configure it so that a function is called whenever an item is selected.
No matter which solution you use, you will need a function that ultimately calls the curselection method of the listbox to get a list of indices. You can then call the get method to get the selected item or items.
Here's a function definition that will print the selected item, or print "no selection" if nothing is selected. So that it can be resused without modification. we'll define it to take the listbox as an argument.
Note: this example assumes the widget only supports a single select, to keep it simple:
def print_selection(listbox):
selection = listbox.curselection()
if selection:
print(f"selected item: {listbox.get(selection[0])}")
else:
print("nothing is selected")
Using a button
To call this from a button is straight-forward. We just create a button after we create the listbox, and use the command attribute to call the function. Since the function we wrote earlier needs a parameter, we'll use lambda to create a temporary function for the button.
button = tk.Button(root, text="Print Selected Item", command=lambda: print_selection(lst))
button.pack()
Calling the function when the selection is made
To call the function whenever the user changes the selection, we can bind a function to the <<ListboxSelect>> event. We'll create a separate function for this, and then pull the widget from the event object that is automatically passed to the function.
def print_callback(event):
print_selection(event.widget)
lst.bind("<<ListboxSelect>>", print_callback)
First of all, the reason you are getting an empty tuple is because you have executed the statements:
sel = lst.curselection()
print(sel)
before you have executed the root.mainloop()
Secondly, your setup for listbox fails to include a StringVar variable to hold your list.
Once the variable has been defined, you should be able to use the .insert statements to add your list items one at a time, or you can initialize the StringVar variable using a .set('hy', 'hello', 'hey') command.
To provide a return of a selected variable, you must incorporate an event handler to determine the list position selected onclick or some other triggering method.
For a pretty clear explanation of these characteristics check here

How can I get user's choice using Tkinter.StringVar?

I am writing a GUI code using Tkinter in python:
var_alg_name = Tk.StringVar(board, 'Bilinear')
Tk.Label(board, text = 'Algorithm Name: ').pack(side = 'left')
ttk.Combobox(board, textvariable = var_alg_name, values=['Bilinear', 'Idw']).pack(side = 'left')
I want to get use's choice when a user choose a option in the list.
By searching help command, I found .trace to call a callback foo, but how can I get the value inside foo?
You simply call var_alg_name.get(), assuming that var_alg_name is accessible in the scope where you're trying to get the value. See Set a default value for a ttk Combobox for an example.

How to create a message box with tkinter?

I've been trying to build a fairly simple message box in tkinter that has "YES" and "NO" buttons. When I push the "YES" button internally it must go and write YES to a file. Similarly, when "NO" is pushed, NO must be written to a file. How can I do this?
You can use the module tkMessageBox for Python 2.7 or the corresponding version for Python 3 called tkinter.messagebox.
It looks like askquestion() is exactly the function that you want. It will even return the string "yes" or "no" for you.
Here's how you can ask a question using a message box in Python 2.7. You need specifically the module tkMessageBox.
from Tkinter import *
import tkMessageBox
root = Tk().withdraw() # hiding the main window
var = tkMessageBox.askyesno("Title", "Your question goes here?")
filename = "log.txt"
f = open(filename, "w")
f.write(str(var))
print str(var) + " has been written to the file " + filename
f.close()
You can assign the return value of the askquestion function to a variable, and then you simply write the variable to a file:
from tkinter import messagebox
variable = messagebox.askquestion('title','question')
with open('myfile.extension', 'w') as file: # option 'a' to append
file.write(variable + '\n')
You can use message box from Tkinter using
# For python 3 or above
from tkinter import messagebox
# For python less than 3
from Tkinter import *
import tkMessageBox
Here's the basic syntax:
messagebox.Function_Name(title, message [, options])
The message boxes are modal and will return a subset of (True, False, OK, None, Yes, No) based on the user’s selection.
So to get the value of message box you just need to store the value in a variable. An example is given below:
res=mb.askquestion('Exit Application', 'Do you really want to exit')
if res == 'yes' :
root.destroy()
There are different type of message boxes or Function_name:
showinfo(): Show some relevant information to the user.
showwarning(): Display the warning to the user.
showerror(): Display the error message to the user.
askquestion(): Ask question and user has to answered in yes or no.
askokcancel(): Confirm the user’s action regarding some application activity.
askyesno(): User can answer in yes or no for some action.
askretrycancel(): Ask the user about doing a particular task again or not.
Message: creates a default information box, or is same as showinfo box.
messagebox.Message(master=None, **options)
# Create a default information message box.
You can even pass your own title, message and even modify the button text in it.
Things you can pass in the message boz:
title: This parameter is a string which is shown as a title of a message box.
message: This parameter is the string to be displayed as a message on the message box.
options: There are two options that can be used are:
default: This option is used to specify the default button like ABORT, RETRY, or IGNORE in the message box.
parent: This option is used to specify the window on top of which the message box is to be displayed.
Links i have used for this answer:
Message box tutorial
Message box documentation
You don't need any other modules to do this!
>>> from tkinter import messagebox
>>> messagebox.askokcancel("Title", "Message")
True
It returns True when the ok/retry/yes button is pressed, and False otherwise.
Other available ones:
askokcancel()
askyesno() or askquestion() (same)
askretrycancel()

Categories