Replace one image with another by uploading. Here first user will select one record ( name of student ) from one OptionMenu. Full details of the record with photo will be displayed on the window. Then user can open the file browser by clicking the upload button and select one new photo. The new photo will be displayed on the window ( preview )
On click of the Update button the old photo will be replaced by the new one.
Download the zip file at the end of this tutorial with all source codes and sample images.
Tkinter GUI application to add, display update and delete Blob column data with image of MySQL table
About MySQL table student_profile.
Our student_profile table has three columns,
id int(2) student varchar(10) profile_photo blob
This can be linked with our student table and photos of the student can be displayed.
Displaying student name for user selection
We defined my_connas connection object
Collect the data from student_profile table by using SQLALchemy.
All student names are displayed as options for the OptionMenu ( om1 ). If any option is selected then my_show() is triggered.
Tkinter OptionMenu with change option →
Here are three steps.
Collect record details on user selection
import tkinter as tk
from tkinter import filedialog
from tkinter.filedialog import askopenfile
from PIL import Image, ImageTk
import io
my_w = tk.Tk()
my_w.geometry("400x250")
my_w.title("www.plus2net.com") # Adding a title
from sqlalchemy import create_engine
from sqlalchemy.exc import SQLAlchemyError
my_conn = create_engine("mysql+mysqldb://root:test@localhost/my_tutorial")
try:
my_row=my_conn.execute("SELECT student FROM student_profile")
my_list = [r for r, in my_row]
except SQLAlchemyError as e:
error=str(e.__dict__['orig'])
print(error)
options = tk.StringVar(my_w)
options.set(my_list[0]) # default value
om1 =tk.OptionMenu(my_w, options, *my_list)
om1.grid(row=1,column=1,padx=30)
global name
def my_show(*args): # on select function
global name
for i in my_list:
if i==options.get():
display_data(i)
name=i
my_font=('times', 12, 'bold')
b2 = tk.Button(my_w, text='Upload File',
command = lambda:upload_file())
b2.grid(row=1,column=4)
my_font1=('times', 18, 'bold')
b3 = tk.Button(my_w, text='Update',font=my_font1,
command = lambda:update_data())
b3.grid(row=1,column=5,padx=10)
global img2
images = [] # to manage garbage collection.
def display_data(name):
query="SELECT id,student,profile_photo FROM student_profile WHERE student=%s"
data=(name,)
my_row=my_conn.execute(query,data)
student = my_row.fetchone()
img = Image.open(io.BytesIO(student[2]))
img = ImageTk.PhotoImage(img)
l1=tk.Label(my_w,text=student[0])
l1.grid(row=1,column=2,ipadx=10)
l2=tk.Label(my_w,text=student[1])
l2.grid(row=1,column=3)
l3 = tk.Label(my_w,image=img )
l3.grid(row=3,column=1)
images.append(img) # garbage collection
Upload the to be replaced photo from local system and display in window ( preview)
global filename2
def upload_file(): # Image upload and display
global filename2,img2
f_types =[('Png files','*.png'),('Jpg Files', '*.jpg')]
filename2 = filedialog.askopenfilename(filetypes=f_types)
img2 = ImageTk.PhotoImage(file=filename2)
b2 =tk.Button(my_w,image=img2) # using Button
b2.grid(row=3,column=2,columnspan=3)#display uploaded photo
images.append(img2) # garbage collection
On click of update button, replace the image with new one.
def update_data(): # Update data to MySQL table
global filename2 , name
fob=open(filename2,'rb') # filename from upload_file()
fob=fob.read()
data=(fob,name) # tuple with data
my_conn = create_engine("mysql+mysqldb://root:test@localhost/my_tutorial")
id=my_conn.execute("UPDATE student_profile set profile_photo \
=%s WHERE student=%s",data)
print("Row Added = ",id.rowcount) # displayed in console
my_w.destroy() # close window after adding data
Full code is here
import tkinter as tk
from tkinter import filedialog
from tkinter.filedialog import askopenfile
from PIL import Image, ImageTk
import io
my_w = tk.Tk()
my_w.geometry("400x250")
my_w.title("www.plus2net.com") # Adding a title
from sqlalchemy import create_engine
from sqlalchemy.exc import SQLAlchemyError
my_conn = create_engine("mysql+mysqldb://root:test@localhost/my_tutorial")
try:
my_row=my_conn.execute("SELECT student FROM student_profile")
my_list = [r for r, in my_row]
except SQLAlchemyError as e:
error=str(e.__dict__['orig'])
print(error)
options = tk.StringVar(my_w)
options.set(my_list[0]) # default value
om1 =tk.OptionMenu(my_w, options, *my_list)
om1.grid(row=1,column=1,padx=30)
global name
def my_show(*args): # on select function
global name
for i in my_list:
if i==options.get():
display_data(i)
name=i
my_font=('times', 12, 'bold')
b2 = tk.Button(my_w, text='Upload File',
command = lambda:upload_file())
b2.grid(row=1,column=4)
my_font1=('times', 18, 'bold')
b3 = tk.Button(my_w, text='Update',font=my_font1,
command = lambda:update_data())
b3.grid(row=1,column=5,padx=10)
global img2
images = [] # to manage garbage collection.
def display_data(name):
query="SELECT id,student,profile_photo FROM student_profile WHERE student=%s"
data=(name,)
my_row=my_conn.execute(query,data)
student = my_row.fetchone()
img = Image.open(io.BytesIO(student[2]))
img = ImageTk.PhotoImage(img)
l1=tk.Label(my_w,text=student[0])
l1.grid(row=1,column=2,ipadx=10)
l2=tk.Label(my_w,text=student[1])
l2.grid(row=1,column=3)
l3 = tk.Label(my_w,image=img )
l3.grid(row=3,column=1)
images.append(img) # garbage collection
global filename2
def upload_file(): # Image upload and display
global filename2,img2
f_types =[('Png files','*.png'),('Jpg Files', '*.jpg')]
filename2 = filedialog.askopenfilename(filetypes=f_types)
img2 = ImageTk.PhotoImage(file=filename2)
b2 =tk.Button(my_w,image=img2) # using Button
b2.grid(row=3,column=2,columnspan=3)#display uploaded photo
images.append(img2) # garbage collection
def update_data(): # Update data to MySQL table
global filename2 , name
fob=open(filename2,'rb') # filename from upload_file()
fob=fob.read()
data=(fob,name) # tuple with data
my_conn = create_engine("mysql+mysqldb://root:test@localhost/my_tutorial")
id=my_conn.execute("UPDATE student_profile set profile_photo \
=%s WHERE student=%s",data)
print("Row Added = ",id.rowcount) # displayed in console
my_w.destroy() # close window after adding data
options.trace('w',my_show)
my_w.mainloop()