Tkinter paste image in textbox from clipboard - python

I am trying to paste get an image from clipboard and paste it into the textbox/label in tkinter. My code is below.
# page4 buttons and functions
f7 = Frame(page4)
f7.grid(row=0, column=0, sticky='NESW')
f8 = Frame(page4)
f8.grid(row=0, column=0, columnspan=2, sticky='NESW')
tb8 = Label(f7, width=82)
tb8.grid(row=0, column=0, sticky='NESW')
tb9 = Text(f7, width=30)
tb9.grid(row=0, column=1, sticky='NESW')
def imgps():
try:
image = root.selection_get(selection='CLIPBOARD')
img = ImageTk.PhotoImage(Image.open(image))
tb8.config(page4, image=img)
tb8.clipboard_clear()
except:
messagebox.showinfo(message="Clipboard is Empty.")
pbtn11 = Button(f8, text="IMAGE", activebackground="lavender",
activeforeground="RoyalBlue", bd="5", bg="aquamarine2",
command=imgps, fg="purple", font=('arial', 10, 'bold'))
pbtn11.grid(row=0, column=0, sticky='NESW')
Nothing appears on the area intended and neither any error is shown up. But, whence I close the application. the Messagebox turns up. Seems like weird coding. Can somebody help.

Here is a simple example of adding an image to the label.
Keep in mind you will need to make sure that a reference to the image is saved or else you will not see an image in your app.
Update:
I believe this updated answer should work for you. The code will try to grab the image from clipboard using the ImageGrab method in PIL if there is one and then it saves the image to a temp folder. We then load that image to the label and then delete the image from the temp folder.
import tkinter as tk
import os
from tkinter import messagebox
from PIL import ImageTk, ImageGrab
root = tk.Tk()
tb8 = tk.Label(root, width=82)
tb8.grid(row=0, column=0, sticky='nsew')
def imgps():
try:
temp_path = "./TempImage/some_image.gif" # Whatever temp path you want here
im = ImageGrab.grabclipboard() # Get image from clipboard
im.save(temp_path) # save image to temp folder
load_for_label = ImageTk.PhotoImage(file=temp_path) # load image from temp folder
tb8.config(image=load_for_label) # set image to label
tb8.image = load_for_label # save reference to image in memory
tb8.clipboard_clear() # clear clipboard
os.remove(temp_path) # delete temp file
except:
messagebox.showinfo(message="Clipboard is Empty.")
pbtn11 = tk.Button(root, text="IMAGE", command=imgps)
pbtn11.grid(row=1, column=0, sticky='nsew')
root.mainloop()
I did try several ways to load the image directly from the clipboard but I kept running into errors. So my above solutions might not be 100% the fastest way to implement this but should work well enough.

Related

How do I update pictures using Tkinter?

I've been having a problem with updating a picture in python using Tkinter. This program is creating a QR code and is displaying it on the window. I have no idea how to update it when it changes, the file name stays the same it just changes.
This is what activates the creation of a QR code
def GenerateQRCode():
# qr code maker 3000
qr = qrcode.QRCode()
qr.add_data("brush")
img = qrcode.make(input.get())
img.save("qrcode.png")
resize_image = img.resize((150, 150))
img2 = ImageTk.PhotoImage(img)
label1 = Label(root, image=img2)
label1.image = img2
label1.pack(pady=50)
It does the job of creating the QR code and dispalying it, however, like I said, no clue how to update it while the file name would stay the same. I could make qrcode1.png, then if new QR code is requested, check if it exists, if so, delete it and make qrcode2.png and display it, viceversa. But I'm sure there is a way how to do it with just one file and maybe even creating the file might be unnecessary. Any comment is welcome. Thank you.
You should create the label with the qr code once, and then update the label whenever you create the new qr code. Here's an example based off of your code:
import tkinter as tk
import qrcode
from PIL import ImageTk
def GenerateQRCode():
global qr_image
qr = qrcode.QRCode()
qr.add_data("brush")
img = qrcode.make(input.get())
img.save("qrcode.png")
resize_image = img.resize((150, 150))
qr_image = ImageTk.PhotoImage(img)
qr_label.configure(image=qr_image)
root = tk.Tk()
input = tk.Entry(root)
qr_image = tk.PhotoImage()
qr_label = tk.Label(root, image=qr_image, width=300, height=300)
button = tk.Button(root, text="Generate code", command=GenerateQRCode)
input.pack(side="top", fill="x")
qr_label.pack(side="top")
button.pack(side="bottom")
root.mainloop()

tkinter window works well only in the first execution

I've been trying to build a tkinter window that has some Check buttons, an image, and a button. I use the Spyder IDE and the code works just fine when I open Spyder and run it for the first time. But when I try to execute again, the image doesn't appear, and also apparently the window does not get destroyed by the button I've created. Is there something wrong with my code?
Here is my code:
import tkinter as tk # GUI configuration
from PIL import ImageTk, Image
# Window to select the analysis actions
config_window = tk.Tk()
config = { # Dictionary with variables that control what the algorithm will do
"EDIT_FILES": tk.BooleanVar(),
"RMS_ANALYSE": tk.BooleanVar(),
"WATERFALL_FFT": tk.BooleanVar()
}
config_window.title('Analysis settings')
label = tk.Label(config_window, text='Please check the boxes corresponding to the operations you would like to do',\
background='red')
label.grid(row=0, sticky='n')
tk.Checkbutton(config_window, text='Edit the files created from the sensor measurements', \
variable=config["EDIT_FILES"]).grid(row=1, sticky='w')
tk.Checkbutton(config_window, text='RMS analysis', \
variable=config["RMS_ANALYSE"]).grid(row=2, sticky='w')
tk.Checkbutton(config_window, text='FFT analysis', \
variable=config["WATERFALL_FFT"]).grid(row=3, sticky='w')
image = Image.open("logo.png").resize((220,80), Image.ANTIALIAS)
logo = ImageTk.PhotoImage(image, size=10)
im_label = tk.Label(image=logo)
im_label.image = logo
im_label.grid(row=4, sticky='w')
tk.Button(config_window, text='Ok', width=10, command=config_window.destroy).grid(row=4, sticky='e')
config_window.mainloop()

Setting Background image to GUI

I made a GUI with few buttons and I want to change the gray background to an image.
my code looks like this:
from tkinter import *
from urlread import givenumbers # my function
""" Setting The Main GUI """
GUI = Tk()
GUI.title('Check GUI')
GUI.iconbitmap('test.ico')
GUI.geometry("400x400")
background_image=PhotoImage('pic.jpg')
background_label = Label(GUI, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
""" Reading Images For Buttons """
A_Im = PhotoImage(file='A.gif')
""" Creating Buttons """
# A Button
A_Button = Button(GUI, image=A_Im, command=givenumbers)
A_Button.grid(column=0, row=1)
GUI.mainloop()
The code runs without error but the background is still gray without any effect.
The problem is in the line background_image=PhotoImage('pic.jpg'). The PhotoImage class only supports GIF-files, which means that it cannot read the file you're specifying. You should try something like this:
#Python 2.7
import Tkinter as tk
from PIL import Image, ImageTk
window = tk.Tk()
image = Image.open('image.jpg')
photo_image = ImageTk.PhotoImage(image)
label = tk.Label(window, image = photo_image)
label.pack()
# Python 3
import tkinter as tk
from PIL import Image, ImageTk
window = tk.Tk()
image = Image.open('image.jpg')
photo_image = ImageTk.PhotoImage(image)
label = tk.Label(window, image = photo_image)
label.pack()
The Image class from the PIL module supports a variety of formats, among which jpeg and png. You can install the PIL module by running pip install pillow in a command prompt or terminal.
If you want to put the widgets on top of the Label, you could indeed using grid to get them on top of each other, but using a Canvas would probably be easier. You can find more about the Canvas widget here.
This can be done without pil also:
from tkinter import *
import tkinter as ttk
""" Setting The Main GUI """
GUI = Tk()
F1=Frame(GUI)
F1=Frame(GUI,width=400,height=450)
F1.place(height=7000, width=4000, x=100, y=100)
F1.config()
F1.grid(columnspan=10,rowspan=10)
F1.grid_rowconfigure(0,weight=1)
F1.grid_columnconfigure(0,weight=1)
photo=PhotoImage(file="C:\\Users\\HOME\\Desktop\\Eshita\\12th\\computer
\\python\\GUI\\math3.gif")
label = Label(GUI,image = photo)
label.image = photo # keep a reference!
label.grid(row=0,column=0,columnspan=20,rowspan=20)
b=ttk.Button(GUI,text="Start")
b.grid(row=8,column=8)
GUI.mainloop()

Saving canvas from tkinter to file

So I followed this post:
How can I convert canvas content to an image?
And when I tried to do as mentioned in the last suggestion, I get the following problem:
When I call it out like this, the image/screenshot is taken too early and therefore the required image won't be captured. Here's the code:
from tkinter import *
from PIL import ImageGrab
root = Tk()
cv = Canvas(root)
cv.pack()
cv.create_rectangle(10,10,50,50)
#cv.create_line([0, 10, 10, 10], fill='green')
cv.update()
#print(root.winfo_width())
def getter(widget):
x=root.winfo_rootx()+widget.winfo_x()
print(x)
y=root.winfo_rooty()+widget.winfo_y()
print(y)
x1=x+widget.winfo_width()
print(x1)
y1=y+widget.winfo_height()
print(y1)
ImageGrab.grab().crop((x,y,x1,y1)).save("em.jpg")
getter(cv)
root.mainloop()
By the way, if there is a simplier solution, I would appreciate it!
The thing is that the saving part will be added to the code dynamically later so the solution should be as light as possible.
Thanks in advance!
PS: Maybe it is even possible to save the canvas without displaying it beforehand? Just by the code?
Below is the code for taking screenshots of just the tkinter canvas. PIL.ImageGrab module does not work in Linux; replaced that with pyscreenshot. Tested this code in Ubuntu 16.04. You may have to check if it operates in Windows/OSx. Please note the remarks in function self._grabtofile.
Remark: In Ubuntu, this script had to be executed directly on commandline/terminal to work. It did not work when executed from IDLE for python3.
Summary:
Able to display the screenschoot of a tkinter canvas and save it to file a
using two events.
Able to screenshot tkinter canvas (w/o displaying it) and save it to
file using one event.
Working code:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
try:
import tkinter as tk # Python 3 tkinter modules
except ImportError:
import Tkinter as tk # Python 2 tkinter modules
from PIL import Image, ImageTk
#from PIL import Image, ImageTk, ImageGrab # For Windows & OSx
import pyscreenshot as ImageGrab # For Linux
class App(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent=parent
file = 'images.jpg'
self.img = Image.open(file)
#self.img.show() #Check to proof image can be read in and displayed correctly.
self.photo = ImageTk.PhotoImage(self.img)
print('size of self.img =', self.img.size)
centerx= self.img.size[0]//2
centery= self.img.size[1]//2
print ('center of self.img = ', centerx, centery)
self.cv = tk.Canvas(self)
self.cv.create_image(centerx, centery, image=self.photo)
self.cv.create_rectangle(centerx*0.5,centery*0.5,centerx*1.5,centery*1.5,
outline='blue')
self.cv.grid(row=0, column=0, columnspan=3, sticky='nsew')
self.snappic=tk.Button(self, text='SNAP', command=self._snapCanvas)
self.snappic.grid(row=1, column=0, sticky='nsew')
self.savepic=tk.Button(self, text='SAVE', command=self._save)
self.savepic.grid(row=1, column=1, sticky='nsew')
self.directsavepic=tk.Button(self, text='Grab_to_File', command=self._grabtofile)
self.directsavepic.grid(row=1, column=2, sticky='nsew')
self.snapsave=tk.Button(self, text='SNAP & SAVE', command=self._snapsaveCanvas)
self.snapsave.grid(row=2, column=0, columnspan=2, sticky='nsew')
def _snapCanvas(self):
print('\n def _snapCanvas(self):')
canvas = self._canvas() # Get Window Coordinates of Canvas
self.grabcanvas = ImageGrab.grab(bbox=canvas)
self.grabcanvas.show()
def _save(self):
self.grabcanvas.save("out.jpg")
print('Screenshoot of tkinter.Canvas saved in "out.jpg"')
def _grabtofile(self):
'''Remark: The intension was to directly save a screenshoot of the canvas in
"out_grabtofile.png".
Issue 1: Only a full screenshot was save.
Issue 2: Saved image format defaults to .png. Other format gave errors.
Issue 3: "ImageGrab.grab_to_file" only able to return full screenshoot
and not just the canvas. '''
print('\n def _grabtofile(self):')
canvas = self._canvas() # Get Window Coordinates of Canvas
print('canvas = ', canvas)
ImageGrab.grab_to_file("out_grabtofile.png", ImageGrab.grab(bbox=canvas))
print('Screenshoot of tkinter.Canvas directly saved in "out_grabtofile.png"')
def _snapsaveCanvas(self):
print('\n def _snapsaveCanvas(self):')
canvas = self._canvas() # Get Window Coordinates of Canvas
self.grabcanvas = ImageGrab.grab(bbox=canvas).save("out_snapsave.jpg")
print('Screencshot tkinter canvas and saved as "out_snapsave.jpg w/o displaying screenshoot."')
def _canvas(self):
print(' def _canvas(self):')
print('self.cv.winfo_rootx() = ', self.cv.winfo_rootx())
print('self.cv.winfo_rooty() = ', self.cv.winfo_rooty())
print('self.cv.winfo_x() =', self.cv.winfo_x())
print('self.cv.winfo_y() =', self.cv.winfo_y())
print('self.cv.winfo_width() =', self.cv.winfo_width())
print('self.cv.winfo_height() =', self.cv.winfo_height())
x=self.cv.winfo_rootx()+self.cv.winfo_x()
y=self.cv.winfo_rooty()+self.cv.winfo_y()
x1=x+self.cv.winfo_width()
y1=y+self.cv.winfo_height()
box=(x,y,x1,y1)
print('box = ', box)
return box
if __name__ == '__main__':
root = tk.Tk()
root.title('App'), root.geometry('300x300')
app = App(root)
app.grid(row=0, column=0, sticky='nsew')
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
app.rowconfigure(0, weight=10)
app.rowconfigure(1, weight=1)
app.columnconfigure(0, weight=1)
app.columnconfigure(1, weight=1)
app.columnconfigure(2, weight=1)
app.mainloop()
Screenshot of GUI:
Screenshot of GUI's tk.Canvas:
I know this is an old post but I just want to share what worked for me, hopefully it will help somebody with similar problem.
import tkinter as tk
from PIL import Image
import io
import os
import subprocess
root = Tk()
cv = Canvas(root)
cv.pack()
cv.create_rectangle(10,10,50,50)
ps = cv.postscript(colormode='color')
img = Image.open(io.BytesIO(ps.encode('utf-8')))
img.save('filename.jpg', 'jpeg')
root.mainloop()
In this solution, you have to have ghostscript and Pillow installed.
For MacOS, install ghostscript with
brew install ghostscript
and Pillow with
pip install Pillow

empty Tkinter window appears in place of image

I am trying to load images dynamically through browse button to Tkinter window but I am getting the empty window. This is the code of callback function of browse button
supformats = [
('Windows Bitmap','*.bmp'),
('Portable Network Graphics','*.png'),
('JPEG ','*.jpg'),
('CompuServer GIF','*.gif'),
]
filename = askopenfilename(filetypes=supformats)
FILENAME = filename
im=Image.open(FILENAME)
w=im.size[0]
h=im.size[1]
root = Tkinter.Tk()
#canvas = Tkinter.Canvas(root, width=w, height=h)
#canvas.grid(row=0,column=0)
#tk_img = ImageTk.PhotoImage(file = FILENAME)
#canvas.create_image(image=tk_img)
im.show()
root.mainloop()
Thanks in advance for everyone who will help
From effbot's explanation http://effbot.org/tkinterbook/photoimage.htm Note that the file is accessed once only, not twice. This assumes you are using the Python Imaging Library in Tkinter as you did not state what image toolkit is being used.
from PIL import Image, ImageTk
image = Image.open("lenna.jpg")
photo = ImageTk.PhotoImage(image)
You can use a PhotoImage instance everywhere Tkinter accepts an image object.
An example:
label = Label(image=photo)
label.image = photo # keep a reference!
label.pack()

Categories