In tkinter, when a button has the focus, you can press the space bar to execute the command associated with that button. I'm trying to make pressing the Enter key do the same thing. I'm certain I've done this in the past, but I can't find the code, and what I'm doing now isn't working. I'm using python 3.6.1 on a Mac.
Here is what I've tried
self.startButton.bind('<Return>', self.startButton.invoke)
Pressing the Enter key has no effect, but pressing the space bar activates the command bound to self.startButton. I've tried binding to <KeyPress-KP_Enter> with the same result.
I also tried just binding to the command I want to execute:
self.startButton.bind('<Return>', self.start)
but the result was the same.
EDIT
Here is a little script that exhibits the behavior I'm talking about.
import tkinter as tk
root = tk.Tk()
def start():
print('started')
startButton.configure(state=tk.DISABLED)
clearButton.configure(state=tk.NORMAL)
def clear():
print('cleared')
clearButton.configure(state=tk.DISABLED)
startButton.configure(state=tk.NORMAL)
frame = tk.Frame(root)
startButton = tk.Button(frame, text = 'Start', command = start, state=tk.NORMAL)
clearButton = tk.Button(frame, text = 'Clear', command = clear, state = tk.DISABLED)
startButton.bind('<Return>', start)
startButton.pack()
clearButton.pack()
startButton.focus_set()
frame.pack()
root.mainloop()
In this case, it works when I press space bar and fails when I press Enter. I get an error message when I press Enter, saying that there an argument was passed, but none is required. When I change the definition of to take dummy argument, pressing Enter works, but pressing space bar fails, because of a missing argument.
I'm having trouble understanding how wizzwizz4's answer gets both to work. Also, I wasn't seeing the error message when I pressed Enter in my actual script, but that's way too long to post.
** EDIT AGAIN **
I was just overlooking the default value of None in Mike-SMT's script. That makes things plain.
Your use of self.startButton.bind('<Return>', self.start) should work fine as long as compensate for the event that the bind will send to the function/method.
Here is a simple example that will work with the enter key as long as the button has focus.
import tkinter as tk
root = tk.Tk()
def do_something(event=None):
print("did something!")
btn = tk.Button(root, text="Do something", command=do_something)
btn.pack()
btn.bind("<Return>", do_something)
#root.bind("<Return>", do_something) will work without the button having focus.
root.mainloop()
This only works when the button has keyboard focus. Also, an argument representing the event object is passed to the callable provided. The former doesn't seem to be the problem, so try:
self.startButton.bind('<Return>', lambda e: self.startButton.invoke())
Related
I have A Note Taking Program and currently I can type in a Keyword in TextBox-1 and hit Enter to get my notes displayed in a TextBox-2.
The only way I can find how to bind Enter to a button is for it to always be bound to that button. Or I can bind Enter to a function. I would rather have it bound to the button/function only if I am currently inside textBox-1.
I don't even know if it is possible because I can not find any references to something similar to my needs.
Currently I have my Enter key bound like this:
root.bind('<Return>', kw_entry)
This calls the function kw_entry when I hit Enter.
def kw_entry(event=None):
e1Current = keywordEntry.get().lower()
if e1Current in notes: # e1Corrent is just the current text in TextBox-1
root.text.delete(1.0, END)
root.text.insert(tkinter.END, notes[e1Current])
root.text.see(tkinter.END)
else:
root.text.delete(1.0, END)
root.text.insert(tkinter.END, "Not a Keyword")
root.text.see(tkinter.END)
For the most part this works fine however I also want to edit the notes being displayed and the problem is I can not hit Enter while in TextBox-2 because Enter is bound to call the function kw_entry. This is a problem because it resets everything in TextBox-2.
Can anyone point me in the right direction?
If you only want the binding to apply when focus is on a specific widget, put the binding on that widget.
In the following example, if you press return while in the text widget then a message will be printed on the console. If you are in the entry widget, that won't happen.
import tkinter as tk
def foo(event):
print("you pressed return")
# the following prevents the enter key from inserting
# a newline. If you remove the line, the newline will
# be entered after this function runs
return "break"
root = tk.Tk()
entry = tk.Entry(root)
text = tk.Text(root)
entry.pack(side="top", fill="x")
text.pack(side="bottom", fill="both", expand=True)
text.bind("<Return>", foo)
root.mainloop()
I have some pretty simple code right now that I am having issues with.
root = Tk()
label1 = Label(root, text ="Enter String:")
userInputString = Entry(root)
label1.pack()
userInputString.pack()
submit = Button(root,text = "Submit", command = root.destroy)
submit.pack(side =BOTTOM)
root.mainloop()
print(userInputString)
When I run the code everything operates as I would expect except
print(userInputString)
for an input asdf in the Entry print will return something like 0.9355325
But it will never be the same value back to back always random.
I am using python 3.5 and Eclipse Neon on a Windows 7 Machine.
Ultimately the goal is to accept a string from the user in the box that pops up and then be able to use that value as string later on. For example, it might be a file path that needs to be modified or opened.
Is Entry not the correct widget I should be using for this? Is there something inherently wrong with the code here? I am new to python and don't have a lot of strong programming experience so I am not even certain that this is set up right to receive a string.
Thanks in advance if anyone has any ideas.
There are two things wrong with your print statement. First, you print the widget, not the text in the widget. print(widget) prints str(widget), which is the tk pathname of the widget. The '.' represents the root window. The integer that follows is a number that tkinter assigned as the name of the widget. In current 3.6, it would instead be 'entry', so you would see ".entry".
Second, you try to print the widget text after you destroy the widget. After root.destroy, the python tkinter wrapper still exists, but the tk widget that it wrapped is gone. The following works on 3.6, Win10.
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text="Enter String:")
entry = tk.Entry(root)
def print_entry(event=None):
print(entry.get())
entry.bind('<Key-Return>', print_entry)
entry.focus_set()
submit = tk.Button(root, text="Submit", command=print_entry)
label.pack()
entry.pack()
submit.pack()
root.mainloop()
Bonus 1: I set the focus to the entry box so one can start typing without tabbing to the box or clicking on it.
Bonus 2: I bound the key to the submit function so one can submit without using the mouse. Note that the command then requires an 'event' parameter, but it must default to None to use it with the button.
The NMT Reference, which I use constantly, is fairly complete and mostly correct.
Consider the following code snippet:
from tkinter import *
import tkinter.filedialog as fd
def mycallback(event):
fname = fd.askopenfilename()
print(fname)
root = Tk()
b1 = Button(root, text='Hello!')
b1.bind('<Button-1>', mycallback)
b1.pack()
root.mainloop()
After pressing the button b1 an open-dialog appears as supposed. If I press OK or CANCEL after choosing a file, the program crashes with exit code 139.
What's the problem here?
I'm using Python 3.4 on OS X 10.6.8.
Calling a function when clicking a button can be done using the button's callback argument.
So instead of binding <Button-1> to the button you should use
b1 = Button(root, text='Hello!', command=mycallback)
You should then also remove the event argument from the mycallback function, since command doesn't pass any arguments.
How this solves your problem, I really dont know. But according to your comment it does.
For more information on the Button (and any other) widget, see effbot.org
I am trying to create a simple popup text entry for the user in which a user enters a text and hits submit (a button). Upon clicking submit, I want the popup entry box to close off and continue on with the rest of the code. Following is a sample code for display that I borrowed from an old post here:
from Tkinter import *
root = Tk()
nameLabel = Label(root, text="Name")
ent = Entry(root, bd=5)
def getName():
print ent.get()
submit = Button(root, text ="Submit", command = getName)
nameLabel.pack()
ent.pack()
submit.pack(side = BOTTOM)
root.mainloop()
print "Rest of the code goes here"
I don't have much experience with Tkinter so I am not sure where and how exactly to call the appropriate functions for closing the entry box after the user hits 'Submit'. My guess is it would have to be inside the getName() function?
If I understand you correctly, then all you need to do is call the root window's destroy method at the end of the getName function:
def getName():
print ent.get()
root.destroy()
Doing so is equivalent to manually clicking the X button in the corner of the window.
Alternate method:
since there isn't much to your popup you could also eliminate several lines of code in your GUI, save some CPU and get pretty much the same output with this:
submitvariablename=raw_input('Please enter a Name')
same functionality and much faster, cleaner.
Just a thought.
In this section of the code, I try to set the button's command to goRun, and also bind the Return key to goRun.
def goRun():
Run.runData(ENTRY=symbolEntry.get(), GREATER=greaterEntry.get(), BETWEEN=betweenEntry.get(), LESSER=lesserEntry.get())
#^ "Run" is a seperate class.
button = Button(app, text="Go Data", command=goRun, fg="blue")
button.pack(side="top", pady=2, padx=10)
app.bind('<Return>', goRun)
When I run the app, and press the Return key, I get this error:
TypeError: goRun() takes no arguments (1 given)
But when I press the button, it runs the command and works just fine.
What am I doing wrong?
Assuming the GUI library you are using is tkinter, this is because when a callback is activated by a keypress, a parameter called event is passed. Try modifying your function definition so it is like this:
def goRun(event=None):
So you are getting the error as your function received a parameter with which it doesn't have a clue what to do. With the event=None we are saying "Don't worry about that argument when it comes along, it's nothing."
You get this error with the Return key because it gives this argument, but it works with your Button as it does not send the argument.