Bind gif image to cursor? - python

Is thre a way to bind and image to the cursor?
I have an event, for the moment it doen'st do much, just this:
from tkinter import *
root = Tk()
def evento(event):
print("explosion"), event.x, event.y
f = Frame(root, width=100, height=100)
f.bind("<Enter>", evento)
f.pack()
root.mainloop()
I'm mostly seen how the events works but I need to bind and image(circle) and then when it enters change it for gif ot at least that's why I'm thinking of, don't know if I can program an animation or not in tkinter

From python docs: try this example
def buildFrame(self):
self.f = Frame(self.master, height=32, width=32, relief=RIDGE,
borderwidth=2)
self.f.place(relx=.5,rely=.5)
#self.f.bind( '<Enter>', self.enterFrame )
#self.f.bind( '<Leave>', self.leaveFrame )
self.f.configure(cursor = 'circle')

Related

tkinter get widget that event got called by

Minimal reproducable Example
from tkinter import *
def test(event):
print(event.widget)
window = Tk()
window.geometry("600x600")
window.bind("<Motion>", test)
frame = Frame(window, bg="red", width=200, height=200)
frame.pack()
frame.bind("<Motion>", test)
window.mainloop()
I want to call the function "test" from different widgets when i move over them. Instead of that, when i hover over the frame, both the window and the frame print that im hovering over the frame, which is not the behaviour i need. Can someone help me achieve the right behaviour?
I think your confusion is in the moment of interpreting when the mouse pointer entered the widget or left the widget. Instead of Motion let's use for example Leave and Enter events to better understand what happens.
I have taken the liberty of including some labels that show which widget we enter and left at each moment.
from tkinter import *
def test_enter(event):
enter.set(event.widget)
def test_left(event):
left.set(event.widget)
window = Tk()
window.geometry("300x300")
window.bind("<Enter>", test_enter)
window.bind("<Leave>", test_left)
frame = Frame(window, bg="red", width=200, height=200)
frame.pack()
frame.bind("<Enter>", test_enter)
frame.bind("<Leave>", test_left)
label1 = Label(frame, text="Enter")
label1.place(relx=0.1, rely=0.4, x= 0.2, y=0.2)
enter = StringVar()
label_enter = Label(frame, textvariable=enter)
label_enter.place(relx=0.3, rely=0.4, x= 0.6, y=0.2)
label2 = Label(frame, text="Leave")
label2.place(relx=0.1, rely=0.6, x= 0.2, y=0.2)
left = StringVar()
label_left = Label(frame, textvariable=left)
label_left.place(relx=0.3, rely=0.6, x= 0.6, y=0.2)
window.mainloop()
Remember that the Frame is inside the Window. I mean that when you enter the Window you have not left root Window, you will continue to be in Window. Or if you enter inside a Label you have not left the Frame.
You could use lambda to pass the widget when the function is run
def test(event, widget):
print(widget)
window = Tk()
window.geometry("600x600")
window.bind("<Motion>", test)
frame = Frame(window, bg="red", width=200, height=200)
frame.pack()
frame.bind("<Motion>", lambda: test(frame))
window.mainloop()
You just need to change two lines
def test(event, widget):
print(widget)
and
frame.bind("<Motion>", lambda: test(frame))

Can you make a functional invisible button in tkinter?

Can I make a button that is functional yet isn't visible? I've looked into a bunch of Tkinter threads, but when I tested the codes, they all led to the button completely disappearing and being disabled. Here is what I've got so far:
import tkinter as tk
import time
app=tk.Tk()
app.minsize(500, 500)
#button function
def move():
button.config(state='disabled')
for i in range(50):
frame.place(x=250+i)
frame.update()
time.sleep(0.01)
frame.place(x=250, y=250)
button.config(state='normal')
block=tk.Frame(app, height=50, width=50, bg='red')
frame=tk.Frame(app, height=400, width=400, bg='blue')
#button I wish to be invisible
button=tk.Button(app, text='clickme', command=move)
button.place(x=40, y=40)
frame.place(x=250, y=250, anchor='center')
block.place(x=50, y=50)
app.mainloop()
No, you cannot make an invisible button in tkinter. It must be on the screen for the user to be able to click it.
You can, however, react to clicks anywhere in the window without the need to create a button.
You can set buttons bg and fg same as the frame/root color and set borderwidth=0. This will create a invisible button.
For example refer this
from tkinter import *
root = Tk()
masterFrame = Frame(root, bg='orange', height=300, width=600)
masterFrame.grid(row=0, column=0, sticky='nsew')
Button(masterFrame, text="Invisible button", bg='orange', fg='orange', borderwidth=0).pack()
root.mainloop()
There's a little more to it than just seting the fg and bg, but yeah it can be done.
#! /usr/bin/env python3
from tkinter import *
color = 'SlateGray4'
width, height = 300, 150
desiredX, desiredY = width *0.5, height *0.75
root = Tk() ; root .title( 'Snozberries' )
root .geometry( f'{width}x{height}' )
root .bind( '<Escape>', lambda e: root .destroy() )
root .configure( bg = color )
def one(): ## takes many parameters during construction
print( 'Found a button!' )
def two( event ):
## print( f'x: {event .x}, y: {event.y}' )
if event .x >= desiredX -25 and event .x <= desiredX +25 \
and event .y >= desiredY -25 and event .y <= desiredY +25:
print( 'Found another button!' )
Label( root, bg=color, text='We are the musicmakers,' ) .pack()
Label( root, bg=color, text='and we are the dreamers of the dreams.' ) .pack()
Button( root, bg=color, fg=color, activebackground=color, activeforeground=color,
highlightbackground=color, borderwidth=0, command=one ) .pack()
Label( root, bg=color, text='Button, button' ) .pack()
Label( root, bg=color, text="who's got the button?" ) .pack()
root .bind( '<Button-1>', two )
root .mainloop()

How to use “command” in canvas_image just like in Button ? Tkinter

I have a code that is working perfectly, but I want a clickable functionality in my image so that it will redirect to frame.
from tkinter import *
def onObjectClick1(event):
print("1")
canv.itemconfig(obj1, image=my_pic2)
canv.tag_bind(obj1, '<Leave>', onObjectClick2)
def onObjectClick2(event):
print("2")
canv.itemconfig(obj1, image=my_pic1)
canv.tag_bind(obj1, '<Enter>', onObjectClick1)
root = Tk()
canv = Canvas(root, width=300, height=300)
my_pic1 = PhotoImage(file="start000-before.png")
my_pic2 = PhotoImage(file="start000-after.png")
obj1 = canv.create_image(50,50,image=my_pic1, anchor=NW)
canv.tag_bind(obj1, '<Enter>', onObjectClick1)
canv.tag_bind(obj1, '<Leave>', onObjectClick2)
canv.pack()
root.mainloop()
Please help me out, I'm new in Tkinter.
At the moment you are binding to the Enter and Leave events. To bind to the click event you need to use Button-1
canv.tag_bind(obj1, '<Button-1>', onMouseButton1Click)
The canvas and canvas widgets don't support the command property as other tkinter widgets.
You can create a window inside a tkinter canvas which can contain normal tkinter widgets. In the below example, I create a window which contains a button. This can then use command in the normal way
from tkinter import *
def PressMeCmd():
print("You pressed me")
root = Tk()
canv = Canvas(root, width=300, height=300)
button = Button(canv,text="Press Me",command=PressMeCmd)
window = canv.create_window(0,0,window=button)
canv.pack()
root.mainloop()
You can use create_window() to put a Button inside a Canvas:
from tkinter import *
def on_click():
print('button clicked')
root = Tk()
canv = Canvas(root, width=300, height=300)
canv.pack()
my_pic1 = PhotoImage(file="start000-before.png")
my_pic2 = PhotoImage(file="start000-after.png")
btn = Button(canv, image=my_pic1, command=on_click)
btn.bind('<Enter>', lambda e: btn.config(image=my_pic2))
btn.bind('<Leave>', lambda e: btn.config(image=my_pic1))
canv.create_window(50, 50, window=btn, anchor=NW)
root.mainloop()

How to call Turtle window from a GUI

I'm trying to open a Turtle window from a GUI to select a position on the image with a mouse click. The x and y coordinates are then returned as an input to the GUI.
Here is a minimal working example:
from tkinter import *
from tkinter import font as tkFont
import turtle
xclick = 0
yclick = 0
def callback3():
getcoordinates()
def getcoordinates():
screen = turtle.Screen()
screen.setup(400, 400)
screen.bgpic("stunden.gif")
screen.onscreenclick(modifyglobalvariables)
def modifyglobalvariables(rawx,rawy):
global xclick
global yclick
xclick = int(rawx//1)
yclick = int(rawy//1)
print(xclick)
print(yclick)
turtle.bye()
root = Tk()
helv30 = tkFont.Font(family='Helvetica', size=30)
button1 = Button(root, text = "1", width=3, font=helv30, borderwidth=0, command=callback3)
button1.grid(row=0, column=0, padx=5, pady=0)
root.mainloop()
Then the error image "pyimage2" doesn't exist shows up. I found out, that it has something to do with two instances of Tk, as there is the root and the turtle window and that I should solve it with Toplevel(). However, after hours of research and try and error I still could not come up with the right solution to make my code work. Any help is greatly appreciated.
Here's how to implement it directly in tkinter — so no turtle module required — as I suggested earlier in a (now-deleted) comment:
from tkinter import *
from tkinter import font as tkFont
CLOCK_IMAGE_PATH = 'clock.png'
xclick, yclick = 0, 0
def callback3():
window = Toplevel()
window.title("Stunden")
img = PhotoImage(file=CLOCK_IMAGE_PATH)
img_width, img_height = img.width(), img.height()
window.minsize(width=img_width, height=img_height)
canvas = Canvas(window, width=img_width, height=img_height)
canvas.pack()
canvas.image = img # Keep reference to avoid image being garbage collected.
canvas.create_image(0, 0, anchor='nw', image=img)
canvas.bind("<Button-1>", get_coordinates) # Set up event-handler callback.
def get_coordinates(event):
global xclick, yclick
xclick = int(event.x // 1)
yclick = int(event.y // 1)
print(f'xclick={xclick}, yclick={yclick}')
root = Tk()
helv30 = tkFont.Font(family='Helvetica', size=30)
button1 = Button(root, text="1", width=3, font=helv30, borderwidth=0, command=callback3)
button1.grid(row=0, column=0, padx=5, pady=0)
root.mainloop()

Create a tkinter image button without a border

I have seen some posts on this topic and have tried the suggestions without success. I want to create a tkinter button using an image. The code below creates the button just fine, but it draws a thin border beyond the image that looks ugly. How can I get rid of the button border? I am using Python 3.5 on Mac OS X 10.12.3.
Here's the code:
from tkinter import *
from tkinter import ttk
sDefaultImage = None
def sStockPileObserver():
print("Button clicked")
def main():
global sDefaultImage
sRoot = Tk()
sMainFrame = ttk.Frame(sRoot, padding="3 3 12 12")
sMainFrame.grid(column=0, row=0, sticky=(N, W, E, S))
sMainFrame.columnconfigure(0, weight=1)
sMainFrame.rowconfigure(0, weight=1)
sMainFrame.rowconfigure(2, minsize=85)
sDefaultImage = PhotoImage(file='backDimmed.gif')
s = ttk.Style()
bg = s.lookup('TFrame', 'background')
s.configure("SolitaireCard.TButton", borderwidth=0, background=bg, highlightbackground=bg, \
highlightthickness=0, activebackground=bg, activeforeground=bg, padx=0)
sStockPileButton = ttk.Button(sMainFrame, image=sDefaultImage, style="SolitaireCard.TButton", width=0, command=lambda: sStockPileObserver())
sStockPileButton.grid(column=1, row=1, sticky=(W, E), padx=0)
return sRoot
sRoot = main()
sRoot.mainloop()
Here is what it produces:
On OSX and Windows you don't have much control over the appearance of buttons.
One solution is to create a button from a label or canvas. You have to add your own bindings to handle clicks, but that's pretty simple to do. For the most part, the bindings simply change the border from raised to lowered, and then call a function when you finish the click.

Categories