Getting the coordinates of the button in Tkinter - python

I want to get the coordinates of the button when I click on the button in tkinter. How can I do this? Please help.

The winfo_* methods will give you information about a window. For example, winfo_rootx and winfo_rooty will return the screen (not window) coordinate of the upper left corner of the widget. winfo_x and winfo_y will return the coordinate of the widget relative to its parent. You can get the width and height with winfo_width and winfo_height.

try this small example.
import tkinter as tk
root = tk.Tk()
btn = tk.Button(root, text=str(1))
btn.pack(padx=10, pady=10)
root.update()
widget_x, widget_y = btn.winfo_rootx(), btn.winfo_rooty()
print(f'{widget_x}, {widget_y}')
root.mainloop()

Related

Python's Tkinter Entry not appearing on window

I am trying to make a window that would take an input through an entry and that would be either a web address or ip address and i would use a loop to update the text of a label to show the current ping every second. But I'm stuck at the very beginning because my entry would not appear on my window. Here is my code:
import tkinter as tk
from tkinter import *
window = tk.Tk()
window.title("Server Status")
window.geometry('400x600')
window.resizable(0,0)
canvas = tk.Canvas(window,height=600,width=1000,bg='#263D42')
canvas.pack()
txtf=tk.Entry(window, width=10)
txtf.pack()
window.mainloop()
Where am I going wrong? I have tried it with several changes but still cant get it to appear there. Any help would be appreciated.
Thanks.
Your entry is below the canvas, but because (1) your window geometry specifies a smaller size than that requested for the canvas, and (2) you set it to be non resizable, you can never access it.
Choose how to resolve this conflict; the example below sets the size of the canvas, and lets the window resize to enclose all its widgets.
import tkinter as tk
window = tk.Tk()
window.title("Server Status")
canvas = tk.Canvas(window, height=600, width=1000, bg='#263D42')
canvas.pack()
txtf = tk.Entry(window, width=10)
txtf.pack()
window.mainloop()

How do I change the size of a tkinter canvas through a new window?

So I have one Tkinter screen that has a canvas. I want to change the size of the canvas by creating a new window that has entry widgets. So I created a new screen and added 2 entry widgets. I want to get the value from those widgets and based on that...it should change the size of the canvas. I tried to do this for an hour, but no luck. Please assist me.
Here is my code
from tkinter import *
# create root window
root = Tk()
# Create Canvas
canvas = Canvas(root, width=50, height=50)
# Create an additional window (the one that is used to enter the new geometry)
dialog = Toplevel(root)
# Add entry widgets for width and height to the new window
width_entry = tk.Entry(dialog)
height_entry = tk.Entry(dialog)
# Add a button to the new window that applies the given width and height
apply_button = Button(dialog, text = 'Apply geometry', command = lambda: canvas.geometry(width_entry.get()+'x'+height_entry.get()))
# Its not possible to get the geometry of a canvas in tkinter...so how do I change the size.
# display the entry boxes and button
width_entry.pack()
height_entry.pack()
apply_button.pack()
# start the tk mainloop
root.mainloop()
Please Assist me
The command you are looking for is canvas.config
Here, I have adjusted the given code:
import tkinter as tk
# create root window
root = tk.Tk()
# Create Canvas
canvas = tk.Canvas(root, width=50, height=50)
canvas.pack()
# Create an additional window (the one that is used to enter the new geometry)
dialog = tk.Toplevel(root)
# Add entry widgets for width and height to the new window
width_entry = tk.Entry(dialog)
height_entry = tk.Entry(dialog)
# Add a button to the new window that applies the given width and height
apply_button = tk.Button(dialog, text = 'Apply geometry', command = lambda: canvas.config(width=width_entry.get(), height=height_entry.get()))
# display the entry boxes and button
width_entry.pack()
height_entry.pack()
apply_button.pack()
# start the tk mainloop
root.mainloop()
I also changed a couple other things:
You imported * from tkinter, but for some items you still led with tk.; I changed them all to match that and switched the import to match as well. (You could still use *, but then just don't have the leading tk.s.)
The canvas was never packed so you could never see what was going on there.
One more suggestion, that line where you make the button is really long. Maybe make a function that does what the lambda does and assign its command to that function instead of a lambda. You can probably see that a line that long is even hard to read here much less if someone (maybe a future version of yourself) was to try to read your code, and edit it or make sense of it. Generally, try to keep all lines down to 80 characters.
Let us know if you have any more questions etc.

How to access entries beyond the window size in Tkinter

I am creating a form with 40 labels and entries. The problem is that I can enter till 20 after that the window size reaches the maximum and I cannot see entries below it. How do I integrate a scrolling option in Tkinter main window? I know that scrollbar cannot be integrated into main window and only to widgets. I want something so that I can either scroll using mouse or arrow keys or anything to see below content. Below is my code:
from Tkinter import *
root = Tk()
root.title('test')
root.geometry("400x400")
for i in range(40):
Label(root, text="Field {} ".format(i)).grid(row=i,column=0)
value=Entry(root).grid(row=i,column=1)
root.mainloop()
Output image
ListBox
Scrollbars are almost always used in conjunction with Listbox, Canvas or Text widget. To connect a vertical scrollbar to one of these widgets you have to do two things:
Set the widget’s yscrollcommand callbacks to the set method of the scrollbar.
Set the scrollbar’s command to the yview method of the widget.
Example
from tkinter import *
master = Tk()
scrollbar = Scrollbar(master)
scrollbar.pack(side=RIGHT, fill=Y)
listbox = Listbox(master, yscrollcommand=scrollbar.set)
for i in range(40):
listbox.insert(END, Label(master, text=f"Field {i} "))
listbox.insert(END, Entry(master))
listbox.pack(side=LEFT, fill=BOTH)
scrollbar.config(command=listbox.yview)
mainloop()

Unable To Repeatedly Get TKinter Window Dimensions

Recently I tried creating the function in which all items on a TKinter GUI will resize themselves to fit the screen, but I cannot seem to figure out how to do this. I did try this:
from tkinter import *
root = Tk()
root.geometry("710x300")
def dimloop():
root.update()
screenwidth = root.winfo_screenwidth()
print(root.winfo_screenwidth())
button.config(width=round(screenwidth/7.1))
root.after(10, dimloop)
button = Button(root, text = 'Hello', width=100)
button.place(x=0, y=0)
dimloop()
root.mainloop()
But That Did Not Work. Does Anyone Know Any Way To Do This?
The screenwidth function returns the width of the physical screen. That's not going to change.
If you want the width of the root window you should use root.winfo_width(). There's no point in doing this in a loop, you can get the width of the screen and then set the window width and height using the geometry method to force it to be a particular size.

Widgets disappear when main window moved off screen

I have a tkinter window that I have given a background picture by creating a Label widget with a PhotoImage instance (referencing the image instance through Label attributing).
However when I run the script and move the main window below the start menu (am using Windows 10) or past the sides of the screens for even one moment, all the widgets packed onto the Label (w/ background pic) completely disappear.
They only come back (somewhat) upon hovering over them with the mouse it seems. Also the background picture remains and continues to fill the screen. Could it be that the background picture Label is being "lifted" and makes it seem like the widgets are disappearing? If so, how can I prevent this from happening?
The fix that I have found for now is to not use a Label with a PhotoImage as the parent "frame", but instead use a typical Frame widget with only a background color, but this is not ideal.
import tkinter as tk
root = tk.Tk()
root.geometry('600x350+600+300')
root.resizable(width=False, height=False)
boxBg = '#666'
frameBg = '#fff'
#problem method
backgroundImg = tk.PhotoImage(file='program_media/background.png')
bgFrame = tk.Label(root, image=backgroundImg)
bgFrame.image = backgroundImg
#less than ideal solution so far
#bgFrame = tk.Frame(root, bg='#fff')
bgFrame.pack(expand=1, fill=tk.BOTH)
mainFrame = tk.Frame(bgFrame)
mainFrame.pack(side=tk.TOP)
title = tk.Label(mainFrame, text='Test String')
title.pack(side=tk.TOP)
#widget creation code packed within mainFrame
#...
#... All these widgets (including mainFrame above) are disappearing
#...
#end of widget creation code
root.mainloop()
See what I mean in this screenshot of BEFORE and AFTER moving the main window below the start menu.

Categories