Problem
I have a simple tkinter GUI application where I show an image in a label widget and use a horizontal scale widget to zoom the image. However, whenever I increase the image size, the window resizes (as desired), which changes the location of the scale widget. The scale widget moves right, which means that the mouse is left relative to the scale widget. The image flickers between big and small.
Question / possible solutions
I know I can use event bindings to react only to the mouse release event (as in TkInter, slider: how to trigger the event only when the iteraction is complete?), but this gives less feedback to the user.
One solution would be to only increase the window size but never automatically decrease it. Is this possible?
Another solution would be to suspend window resizing / fix the window size at the current geometry while the mouse is pressed and allow automatic rescaling only when the mouse is released. How would I achieve this?
Are there any other solutions for this problem.
Sample code:
from PIL import Image, ImageTk
import tkinter as tk
from tkFileDialog import askopenfilename
class Window(object):
def __init__(self):
self.root = tk.Tk()
filename = askopenfilename(
parent=self.root,
title='Please choose the image',
filetypes = [("Image Files", ("*.jpg", "*.png", "*.bmp")),
("All", "*")]
)
self.imgPIL = Image.open(filename)
self.imgTk = ImageTk.PhotoImage(self.imgPIL)
self.imgDisplay = tk.Label(self.root, image = self.imgTk)
self.imgDisplay.grid(row=2, column=0, columnspan=2)
tk.Label(
self.root,
text="Zoom:"
).grid(row = 0, column = 0, sticky = "E")
tk.Scale(
self.root, from_=1, to_=15,
orient=tk.HORIZONTAL,
command = self.resize
).grid(row = 0, column = 1, sticky = "W")
def resize(self, zoom):
newsize = (self.imgPIL.size[0]*int(zoom),
self.imgPIL.size[1]*int(zoom))
scaledImg = self.imgPIL.resize(newsize, Image.NEAREST)
self.imgTk = ImageTk.PhotoImage(scaledImg)
self.imgDisplay.configure(image = self.imgTk)
def show(self):
self.root.mainloop()
if __name__ == "__main__":
window = Window()
window.show()
Example
I drag the handle on the scale widget slightly right
This resizes the image & window, now the cursor position is on the left of the handle
On the next slight move of the mouse, the image is smaller again.