This code is a tutorial from youtube. The given code is supposed to print right on the right click of the mouse on the console and same for the left click but it is not doing so. I think the problem is with the bind function.
I am using python 3.7 which already have tkinter package in it, what can I do to make it work, thank you very much.
from tkinter import *
root = Tk()
def leftclick(event):
print("left")
def rightclick(event):
print("right")
frame = Frame(root, width=300, height=300)
frame.bind("button-1", leftclick)
frame.bind("button-2", rightclick)
frame.pack()
root.mainloop()
I expect the program to print 'left' in the console on the left click of the mouse inside the tk window and same for right click
First, as already noted in comments, the mouse button events need <...>. About the rightclick not working: This is because the even for the right mouse button is actually <Button-3>, whereas <Button-2> is the middle mouse button (or pressing down on the mouse wheel).
frame.bind("<Button-1>", leftclick)
frame.bind("<Button-3>", rightclick)
This may be a bit unintuitive if you think of the right mouse button as the "secondary" button, but makes sense if you just enumerate the buttons from left to right. This is AFAIK also consistent with all (most?) other UI frameworks and languages.
Related
It's been a number of years since I asked for help. I'm creating a number of drag and drop buttons inside a frame. When the button is released It triggers that works fine. I have set up a boundary inside the button_drag().The problem I'm having is if the button is dragged right up to the boundary the button fails to trigger. Of course code is worth a thousand words so I made up a small code which shows the approach i'm taking using just one button. I have tried placing the button inside it's own canvas and fiddled around with mouse Info. I hope someone can help. thanks
root = Tk()
root.geometry("300x300")
frame = Frame(root,bg="grey40")
frame.config(width=200,height = 200)
frame.pack()
frame.place(x=150, y=150, anchor=CENTER)
def button_push():
print("Button Pressed")
def button_drag(event):
global Yevent
x = event.x + event.widget.winfo_x()
y = event.y + event.widget.winfo_y()
Yevent = y
if y > 180:
y = 180
event.widget.place(x=x, y=y, anchor="s")
button = Button(frame, text="button1", font='TkDefaultFont', fg="slate grey",command=lambda: button_push())
button.place(x=50,y=50)
button.bind("<B1-Motion>",button_drag)
root.mainloop()
The normal behavior of buttons is to not call their command if you release the mouse button when the cursor is not over the button. This allows the user to prevent the button from being clicked if they change their mind after pressing the button.
If you want the button to be triggered no matter where the cursor is when the user releases the button, you'll have to add your own binding.
You'll want to have your binding return the string "break" so that the default behavior doesn't also cause the button to trigger.
button.bind("<ButtonRelease-1>", lambda event: event.widget.invoke() and "break")
I'm new using tkinter on python and I would like to develop a program that can Drag and Drop a button pressing other one... I will try to explain : I have button 'A' that will create a new button 'B' and I want to Drag the New button to another place
Any help
Thanks
The tkinter.dnd module, as suggested by j_4321 in comments.
Here is some sample code using that library to do what you have said:
from tkinter import *
from tkinter.dnd import Tester as DragWindow, Icon as Dragable
# Make a root window and hide it, since we don't need it.
root = Tk()
root.withdraw()
# Make the actual main window, which can have dragable objects on.
main = DragWindow(root)
def make_btn():
"""Make a new test button."""
# The functional part of the main window is the canvas.
Dragable('B').attach(main.canvas)
# Make a button and bind it to our button creating function.
Button(main.top, text='A', command=make_btn).pack()
# Start the mainloop.
mainloop()
Is there a best practice for making a tkinter button momentarily change color when it is selected (so the user gets a visual feedback that the button was pressed).
I have read it is not a good idea to use time.sleep() in a tkinter GUI.
When my button is pressed, the code happens so fast that even when I have a button.config() command to change color, it doesn't occur without using time.sleep()
Any suggestions?
I think this may be what you want:
Button(background=normal_color, foreground=text_color,
activebackground=pressed_color, activeforeground=pressed_text_color)
This changes the button from normal_color to pressed_color when the button is pressed.
It's actually a simple question with a simple answer but I had to look everywhere too. Finally found this answer by reading http://effbot.org/tkinterbook/button.htm.
You can change the color upon clicking, then use the after method to reset the color back to the original, after some time has passed
import tkinter as tk
def reset_color():
bt['fg'] = 'black'
def clickme():
print('clicked')
bt['fg'] = 'red'
root.after(2000, reset_color) # after 2 seconds
root = tk.Tk()
bt = tk.Button(root, text='will color for a while\nafter clicked', command=clickme)
bt.pack()
root.mainloop()
I would like to press a button and have it print the location of the cursor X/Y coordinates as well as the content of the button in tkinter.
I'm new to python and I haven't found any way to do this. Can anyone help me finding the right start on this issue?
You can use the bind the button click event to print the location clicked, here's an example of how you can do that.
import tkinter as tk
def print_location(event):
print(event.x, event.y)
root = tk.Tk()
button = tk.Button(root, text='click me')
button.bind("<Button-1>", print_location)
button.pack()
root.mainloop()
Note: using external modules such as pyautogui is not recommended and unnecessary.
I'm currently creating an adventure game and I want to bind alt+a to my callback. It doesn't do what I want, so I have two questions:
Is it possible to bind a function to a Label, too?
Why does this (simplyfied) code doesn't work?
Here is the code:
import tkinter as tk
dw = tk.Tk()
dw.title('Hearts')
def play(event):
print('This is the test.')
areal = tk.Frame(master=dw, width=1200, height=600, bg='blue')
areal.pack_propagate(0)
areal.pack(fill=tk.BOTH, expand=bool(dw))
areal.bind("<Alt-A>", play)
dw.mainloop()
It doesn't give me an error, but it doesn't do anything when I click the Frame and afterwards press alt+a. What is wrong here?
EDIT:
import tkinter as tk
def go_fwd(event):
areal.focus_set()
print(event.x, event.y)
dw = tk.Tk()
dw.title('Adventure')
areal = tk.Frame(master=dw, width=20000, height=600, bg='blue')
areal.pack_propagate(0)
areal.pack(fill=tk.BOTH, expand=bool(dw)-100)
areal.focus_set()
dw.bind("<Alt-A>", go_fwd)
enter = tk.Frame(master=dw, width=20000, height=100, bg='cyan')
enter.pack(fill=tk.X)
enterentry = tk.Text(master=enter, width=100, height=4, bg='white')
enterentry.pack()
enterbutton = tk.Button(master=enter, text='Senden', bg='red')
enterbutton.pack()
dw.mainloop()
Here is the complete code.
Is it possible to bind a function to a Label, too?
You can bind to any widget you want. However, if you bind key events, the bindings will only work if the widget has focus. By default, most widgets other than Entry and Text don't get focus unless you explicitly set the focus to them.
Note: only one widget can have keyboard focus at a time.
You can also set a binding to the root window, which will cause it to fire no matter what widget has focus.
For a more thorough explanation of how key bindings are processed, see this answer: https://stackoverflow.com/a/11542200/7432
Why does this (simplyfied) code doesn't work?
It doesn't work the way you expect because the binding is on a Frame widget, but that widget doesn't have the keyboard focus. You could give it focus with something like this:
areal.focus_set()
Or, you could only give it focus after you click on the frame, by creating a binding on a mouse click:
areal.bind("<1>", lambda event: areal.focus_set())
Note: you are binding to a capital "A", so make sure when you test that you're pressing control-alt-a
You need to bind to dw instead of your frame.
So, you can do dw.bind("<Alt-A>", play).
A minor note, Alt-A will bind to the uppercase A as expected, so you'd have to click Alt+Shift+A on your keyboard. Doing Alt+A on your keyboard won't work, you'd have to bind to Alt-a for this to work.
The main window has keyboard focus. Or, alternatively you can leave the bind on the frame and just do areal.focus_set() to set the focus to the frame.