[Raspberri PI 3 b+, Python]
First of all, I would apologizr gor my language skill.
I am coding the Tkinter for keyboard event, The keyboard command button like (Up) (Down) is work well but the normal charactors dosen't work (Such as 1-9, A-Z)
I have tired
frame.bind('<Left>', leftKey) # THIS OK
frame.bind('<Right>', rightKey) # THIS OK
but
frame.bind('<1>', leftKey) # Not work
frame.bind('1', leftKey) # Not work
frame.bind("1", leftKey) # Not work
I would like to use keyboard charactor botton to works properly same as Up, Down button.
"1" and '1' should work. "<1>" represents mouse button 1.
If you are binding to a frame, you must make sure that it has keyboard focus. By default Frames do not have keyboard focus.
For example, to force the keyboard focus to a frame you need to call focus_set:
frame.focus_set()
This could happen if the frame doesn't have the focus so frame.bind('<1>', leftKey) will not work.
You can check which widget has the focus by print frame.focus_get().
There are two ways you can solve your problem.
Either you set focus to the frame before binding callback
Example:
from tkinter import *
root = Tk()
root.geometry('100x100+100+100')
frame = Frame(root)
frame.pack()
frame.focus_set() # This will get the frame in focus.
# If the frame is in focus the bind will work.
frame.bind( "1", lambda _: print(frame.focus_get()) )
root.mainloop()
Or
Just bind it to the main window.
from tkinter import *
root = Tk(). # Main window
# bind the callback to the main window.
root.bind( '1', lambda k: print(k) )
root.mainloop()
Related
I'm using tkinter to make a python app and I need to let the user choose which key they will use to do some specific action. Then I want to make a button which when the user clicks it, the next key they press as well in keyboard as in mouse will be detected and then it will be bound it to that specific action. How can I get the key pressed by the user?
To expand on #darthmorf's answer in order to also detect mouse button events, you'll need to add a separate event binding for mouse buttons with either the '<Button>' event which will fire on any mouse button press, or '<Button-1>', (or 2 or 3) which will fire when that specific button is pressed (where '1' is the left mouse button, '2' is the right, and '3' is the middle...though I think on Mac the right and middle buttons are swapped).
import tkinter as tk
root = tk.Tk()
def on_event(event):
text = event.char if event.num == '??' else event.num
label = tk.Label(root, text=text)
label.place(x=50, y=50)
root.bind('<Key>', on_event)
root.bind('<Button>', on_event)
root.mainloop()
You can get key presses pretty easily. Without knowing your code, it's hard to say exactly what you will need, but the below code will display a label with the last key pressed when ran and should provide enough of an example to show you how to adapt it to your program!
from tkinter import Tk, Label
root=Tk()
def key_pressed(event):
w=Label(root,text="Key Pressed: "+event.char)
w.place(x=70,y=90)
root.bind("<Key>",key_pressed)
root.mainloop()
I've been trying to create a message box when a button turns from disabled to active but when the button actually turns from disabled to active for some reason my callback is not even being called I've tried to get it working so for quite a bit of time now and I'm stuck.
Here is an example of the problem:
from tkinter import *
from tkinter import Tk
def disable_and_activate():
b.config(state = DISABLED)
b.config(state = ACTIVE)
def is_working(event):
print('working')
root = Tk()
b = Button (root, text = 'click me', command = disable_and_activate)
b.pack()
b.bind('<Activate>', is_working)
root.mainloop()
Console:
the button is clicked but there's nothing printed on the console
The <Activate> event is not triggered when you set the state of the button to "active". The event is triggered when the window becomes the active window.
For example, when I run your code on my OSX machine, if I click on some other application to give it focus and then I click back to the tkinter window, the event will fire when the tkinter window becomes the active window.
This is explained in the canonical tcl/tk documentation which says this:
Activate, Deactivate
These two events are sent to every sub-window of a toplevel when they change state. In addition to the focus Window, the Macintosh platform and Windows platforms have a notion of an active window (which often has but is not required to have the focus). On the Macintosh, widgets in the active window have a different appearance than widgets in deactive windows. The Activate event is sent to all the sub-windows in a toplevel when it changes from being deactive to active. Likewise, the Deactive event is sent when the window's state changes from active to deactive. There are no useful percent substitutions you would make when binding to these events.
Here the problem was just the code inside the function , It seems like you needed to call EventGenerate('<<Activate>>') I also recommend adding 2 << and 2 >>
So I rewrote the code and its now working perfectly fine:
from tkinter import *
from tkinter import Tk
import tkinter
def disable_and_activate():
b.configure(state=tkinter.DISABLED)
b.configure(state=tkinter.ACTIVE)
b.event_generate("<<Activate>>")
def is_working(event):
print('working')
root = Tk()
b = Button (root, text = 'click me', command = disable_and_activate)
b.pack()
b.bind('<<Activate>>', is_working)
root.mainloop()
I've made a program in python with Tkinter that allows you to free draw and choose different colors. I decided to make a button that would close the window instead of clicking the exit button in the top right corner. My question is how do I make the window close when the button is pressed?
If you are using a main loop for your application, then you can use the .destroy() method to release all the resources associated with the window and close the application. You call this method within the command function for your button like so:
from tkinter import *
root = Tk()
frame = Frame(root)
frame.pack(side=LEFT)
button = Button(frame, text="Exit", command=exit)
button.pack()
root.mainloop()
def exit():
root.destroy()
That should close your window. Optionally, the destroy() method may also be used at the end of your main loop if the X button of your application won't close the window immediately.
See these examples for more info:
http://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.destroy-method
http://effbot.org/tkinterbook/tkinter-hello-again.htm
I have an issue with accessing to Tkinter button objects.
My idea that 2nd button is disabled if first button wasn't pressed.
If 1st button is pressed TopLevel window pops up with input fields.
When 3rd button is pressed works my function.And I'd like to change text of 4th button and destroy 3rd button.
I can't do that from my function
self.win = tk.Toplevel()
self.win.geometry('350x200')
self.win.transient(root)
self.win.grab_set()
self.btn_cancel = tk.Button(master=self.win, text='Отмена',
command=self.win.destroy).grid(row=8, column=1)
self.btn_conn = tk.Button(master=self.win, text='Проверить',
command=self.entry_db_check).grid(row=8, column=0)
def entry_db_check(self):
<my code is here>
After all manipulation 2nd button must be active.
I saw that it should work so
self.btn_cancel.destroy()
self.btn_conn['text']='OK'
Should I switch to frames instead of TopLevel window to make it work?
I'm making a program on the Raspberry Pi with a touchscreen display.
I'm using Python Tkinter that has two entry widgets and one on screen keypad. I want to use the same keypad for entering data on both entry widgets.
Can anyone tell me how can i check if an entry is selected? Similar like clicking on the Entry using the mouse and the cursor appears. How can I know that in Python Tkinter?
Thank you.
There is always a widget with the keyboard focus. You can query that with the focus_get method of the root window. It will return whatever widget has keyboard focus. That is the window that should receive input from your keypad.
You can use events and bindigs to catch FocusIn events for your entries.
entry1 = Entry(root)
entry2 = Entry(root)
def callback_entry1_focus(event):
print 'entry1 focus in'
def callback_entry2_focus(event):
print 'entry2 focus in'
entry1.bind("<FocusIn>", callback_entry1_focus)
entry2.bind("<FocusIn>", callback_entry2_focus)