How do you take a screenshot of a particular widget? I keep on getting "how to take screenshot of whole screen" or "how to take screenshot of the window" when searching, but I want to know how to take screenshot of a widget, a Frame, to be exact. I'm afraid that this forum would require me to give them a code snippet, when in reality I don't know what to do. So I'm just asking if this is possible, and how to do it.
PS: I would really appreciate if it is possible to just give a function the widget variable, and then it would go searching for that widget and then take a precise screenshot of it. I know that there is pyautogui which searches for images, I just don't know what I need to do exactly, since this frame isn't an image and it always changes from now and then, so the automation might get confused.
PS: I would really appreciate if it is possible to just give a function the widget variable, and then it would go searching for that widget and then take a precise screenshot of it.
Nope, there is no function that would take the screenshot of the widget. What you can do is use PIL
to take the screenshot of the image. For that you need the coordinates of the frame, which you can get dynamically using methods of widgets.
First you need to install PIL
, so:
pip install Pillow
If on Linux, then PIL.ImageGrab
will not work, so install another library for taking screenshot, instead of PIL
:
pip install pyscreenshot
Here is a modular code that you can use with any widget by passing the widget as an argument to the function:
from PIL import ImageGrab # If on Linux, use `import pyscreenshot as ImageGrab` after installing it
def capture(wid,file_name='img',file_format='png'):
"""Take screenshot of the passed widget"""
x0 = wid.winfo_rootx()
y0 = wid.winfo_rooty()
x1 = x0 + wid.winfo_width()
y1 = y0 + wid.winfo_height()
im = ImageGrab.grab(bbox=(x0, y0, x1, y1)) # bbox means boundingbox, which is shown in the image below
im.save(f'{file_name}.{file_format}') # Can also say im.show() to display it
Now all you need is to implement this function into your code, here is an example:
from tkinter import *
from PIL import ImageGrab # If on Linux, use `import pyscreenshot as ImageGrab` after installing it
root = Tk()
def capture(wid,file_name='img',file_format='png'):
"""Take screenshot of the passed widget"""
x0 = wid.winfo_rootx()
y0 = wid.winfo_rooty()
x1 = x0 + wid.winfo_width()
y1 = y0 + wid.winfo_height()
im = ImageGrab.grab((x0, y0, x1, y1))
im.save(f'{file_name}.{file_format}') # Can also say im.show() to display it
frame = Frame(root,bg='red',width=100,height=185)
frame.pack()
frame.pack_propagate(0) # Make it not auto-resize according to widgets
for i in range(5):
Button(frame,text=f'Button {i}').pack()
Button(root,text='Take screenshot',command=lambda: capture(frame,img_name='frame',img_format='png')).pack()
root.mainloop()
If you are wondering what the coordinates passed into bbox
refers to, then: