Issue
Here is a piece of code that picks up an image path from sqlite3, resize it to match a label/frame size and display it on a tkinter GUI. I don't know or don't remember how to define the variable "final_image," if the variable is only created after the GUI is started.
What I mean by this is that I have a list of records in a ttk.treeview. Each record has an image path inserted in the database. When I click on an item in the treeview, the selection is activating the function preview_image(), then resizes the image to fit an exact frame size on the GUI, and then display it.
The issue here is that until I click a record on the treevew, the variable "final_image" is null, so when I start the GUI, that variable is not defined, and the GUI fails.
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
import sqlite3
def preview_image():
global img_link1, final_image
Find path for selected record.
conn = sqlite3.connect('Equipment.db')
c = conn.cursor()
query = "SELECT c_ipath FROM items WHERE itemID LIKE '%" + record_value + "%'"
c.execute(query)
img_link = c.fetchone()
c.close()
conn.close()
image = Image.open(img_link)
img_link1 = image.copy()
final_image = ImageTk.PhotoImage(image)
def resize_image(event):
new_width = event.width
new_height = event.height
img = img_link1.resize((new_width, new_height))
photo = ImageTk.PhotoImage(img)
img_label.config(image=photo)
img_label.image = photo # avoid garbage collection
root = tk.Tk()
root.title("Title")
root.geometry('600x600')
# --------------------------------------- Tab 1 Image Preview -------------------------------
section3 = tk.Frame(root, background="black")
section3.place(x=10, y=10, height=460, width=500)
img_label = ttk.Label(section3, image=final_image)
img_label.bind('<Configure>', resize_image)
img_label.pack(fill=tk.BOTH, expand=tk.YES)
root.mainloop()
The solution might be very simple and obvious, but I can't see it.
Solution
With the help of acw1668, I solved the issue with one function: I select a record from a treeview. This pulls the file path of the image from the database. Using the filepath, I resize the image on the fly and place it into a canvas. Every time I click a record on the treeview, it runs the preview_image(event) function and changes the image in the img_canvas with the resized image that fits the height of frame. This work for me, and it might help someone else.
The indicated corrections from acw1668 are in the comments below. Do not forget to make "final_img" global.
def preview_image(event):
global final_img
# Find path for selected record.
conn = sqlite3.connect(conndb.data_source)
c = conn.cursor()
query = "SELECT c_ipath FROM items WHERE itemID LIKE '%" + record_value + "%'"
c.execute(query)
img_link = c.fetchone()
c.close()
conn.close()
baseheight = 460
img = Image.open(img_link[0])
hpercent = (baseheight / float(img.size[1]))
wsize = int((float(img.size[0]) * float(hpercent)))
img_resized = img.resize((wsize, baseheight), Image.ANTIALIAS)
final_img = ImageTk.PhotoImage(img_resized)
img_canvas.itemconfigure(image_item, image=final_img)
# --- GUI ----
root = tk.Tk()
root.title("Title")
root.geometry('1120x980+500+20')
section3 = tk.Frame(root, background="black")
section3.place(x=10, y=510, height=460, width=1100)
img_canvas = tk.Canvas(section3, bg="black", highlightthickness=0)
img_canvas.pack(fill=tk.BOTH, expand=tk.YES)
image_item = img_canvas.create_image(1100/2, 460/2, anchor=tk.CENTER)
root.mainloop()
Answered By - Robin Answer Checked By - David Goodson (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.