I can't understand why results of running the 1st and 2nd versions of the below code are different?!. I expect that the both versions resize the image; however, the image is resized only if it has been opened using filedialog.askdirectory (i.e. version 2):
First version:
import os
import tkinter as tk
from tkinter import filedialog, ttk
from PIL import Image, ImageTk
class Manual:
def __init__(self, root):
self.root = root
self.root.title("Manual")
window_width = 800
window_height = 600
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
x = int((screen_width / 2) - (window_width / 2))
y = int((screen_height / 2) - (window_height / 2))
self.root.geometry(f"{window_width}x{window_height}+{x}+{y}")
self.canvas = None
self.folder_path = ""
self.image_files = []
self.current_image = 0
self.total_images = 0
self.image = None
# Option 1:
self.in_path = r"C:\Users\Markazi.co\Desktop\input 3"
self.canvas_frame = tk.Frame(self.root)
self.canvas_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
self.canvas_scrollbar_x = ttk.Scrollbar(self.canvas_frame, orient=tk.HORIZONTAL)
self.canvas_scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
self.canvas_scrollbar_y = ttk.Scrollbar(self.canvas_frame)
self.canvas_scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
self.canvas = tk.Canvas(self.canvas_frame, bg='white', xscrollcommand=self.canvas_scrollbar_x.set,
yscrollcommand=self.canvas_scrollbar_y.set)
self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.canvas_scrollbar_x.config(command=self.canvas.xview)
self.canvas_scrollbar_y.config(command=self.canvas.yview)
def open_folder(self):
# Option 2:
#self.in_path = filedialog.askdirectory()
if self.in_path:
self.image_files = sorted([f for f in os.listdir(self.in_path) if f.lower().endswith('.jpg')])
self.total_images = len(self.image_files)
self.open_image()
def open_image(self):
if self.current_image < self.total_images:
image_file = self.image_files[self.current_image]
self.image = Image.open(os.path.join(self.in_path, image_file))
self.show_image(image_file, self.current_image + 1, self.total_images)
else:
self.canvas.delete("all")
self.canvas.pack_forget() # Hide the canvas
def show_image(self, image_file, current_image, total_images):
if self.image:
width, height = self.calculate_image_size()
self.image = self.image.resize((width, height), Image.LANCZOS)
self.tk_image = ImageTk.PhotoImage(self.image)
self.canvas.config(scrollregion=(0, 0, width, height))
self.canvas.delete("all")
self.canvas.create_image(0, 0, anchor=tk.NW, image=self.tk_image)
def calculate_image_size(self):
if self.image:
window_width = self.root.winfo_width()
window_height = self.root.winfo_height()
border = 20
max_width = window_width - (2 * border)
max_height = window_height - (2 * border)
image_ratio = self.image.width / self.image.height
window_ratio = max_width / max_height
if image_ratio > window_ratio:
width = max_width
height = int(max_width / image_ratio)
else:
width = int(max_height * image_ratio)
height = max_height
return width, height
root = tk.Tk()
root.eval('tk::PlaceWindow . center')
app = Manual(root)
app.open_folder() # Call open_folder() to open the folder only once
root.mainloop()
The second version (using filedialog.askdirectory()):
import os
import tkinter as tk
from tkinter import filedialog, ttk
from PIL import Image, ImageTk
class Manual:
def __init__(self, root):
self.root = root
self.root.title("Manual")
window_width = 800
window_height = 600
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
x = int((screen_width / 2) - (window_width / 2))
y = int((screen_height / 2) - (window_height / 2))
self.root.geometry(f"{window_width}x{window_height}+{x}+{y}")
self.canvas = None
self.folder_path = ""
self.image_files = []
self.current_image = 0
self.total_images = 0
self.image = None
# Option 1:
#self.in_path = r"C:\Users\Markazi.co\Desktop\input 3"
self.canvas_frame = tk.Frame(self.root)
self.canvas_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
self.canvas_scrollbar_x = ttk.Scrollbar(self.canvas_frame, orient=tk.HORIZONTAL)
self.canvas_scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
self.canvas_scrollbar_y = ttk.Scrollbar(self.canvas_frame)
self.canvas_scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
self.canvas = tk.Canvas(self.canvas_frame, bg='white', xscrollcommand=self.canvas_scrollbar_x.set,
yscrollcommand=self.canvas_scrollbar_y.set)
self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.canvas_scrollbar_x.config(command=self.canvas.xview)
self.canvas_scrollbar_y.config(command=self.canvas.yview)
def open_folder(self):
# Option 2:
self.in_path = filedialog.askdirectory()
if self.in_path:
self.image_files = sorted([f for f in os.listdir(self.in_path) if f.lower().endswith('.jpg')])
self.total_images = len(self.image_files)
self.open_image()
def open_image(self):
if self.current_image < self.total_images:
image_file = self.image_files[self.current_image]
self.image = Image.open(os.path.join(self.in_path, image_file))
self.show_image(image_file, self.current_image + 1, self.total_images)
else:
self.canvas.delete("all")
self.canvas.pack_forget() # Hide the canvas
def show_image(self, image_file, current_image, total_images):
if self.image:
width, height = self.calculate_image_size()
self.image = self.image.resize((width, height), Image.LANCZOS)
self.tk_image = ImageTk.PhotoImage(self.image)
self.canvas.config(scrollregion=(0, 0, width, height))
self.canvas.delete("all")
self.canvas.create_image(0, 0, anchor=tk.NW, image=self.tk_image)
def calculate_image_size(self):
if self.image:
window_width = self.root.winfo_width()
window_height = self.root.winfo_height()
border = 20
max_width = window_width - (2 * border)
max_height = window_height - (2 * border)
image_ratio = self.image.width / self.image.height
window_ratio = max_width / max_height
if image_ratio > window_ratio:
width = max_width
height = int(max_width / image_ratio)
else:
width = int(max_height * image_ratio)
height = max_height
return width, height
root = tk.Tk()
root.eval('tk::PlaceWindow . center')
app = Manual(root)
app.open_folder() # Call open_folder() to open the folder only once
root.mainloop()
This is a brief version of a more detailed code. Is this a python bug?
As suggested by ChatGPT 3.5, adding "root.update()" at the end of the code, solved the problem: