Monday, April 11, 2016

Smart TkInter Image Manager for Labels

Just a quick post today.  I've been working on a piece of python software that's tkinter based that requires images to be displayed.  My preferred way of doing this is to use a tkinter.ttk.Label to hold images, but they're aren't very flexible.  To overcome this I wrote a subclass of the tkinter.ttk.Label called TkLabelImage.  It allows images to be easily loaded and displayed by labels while controlling their quality and behaviour when resized.

In the example below a TkLabelImage object is created, it's image behaviour is set, and the file name is specified.

        self.label1 = TkLabelImage(self.frame1)
        self.label1.image_behaviour('dynamic', True, 500)

The first line creates a TkLabelImage object that's a child widget of self.frame1.  After that, the behaviour is set on the next line.  The first argument refers to the image quality desired when the image is resized.  'low'  will resize the image without anti-aliasing, 'high' will use anti-aliasing, and dynamic will resize the image without anti-aliasing, and after a delay in milliseconds defined by the third argument will do a final anti-aliased refresh.  This means that windows can be resized smoothly by only rendering lower quality images when the resize is occurring, but as soon as it's complete a higher quality image is refreshed.  The second argument specifies if the aspect ratio of the image should be preserved.  When the configure event of the main program is called, the following method is called to refresh the image.


The image below is a demonstration of this.  The window is split into two frames that each hold a label.  Each label displays an image.  The first has aspect lock on while the second doesn't.
tkinter window
Comapre the effects of aspect lock

The window below shows the effect of anti-aliasing on the image.  The first image uses it while the second doesn't.
tkinter window
Compare the effects of anti-aliasing

I am by no means a python expert I'm sure there are many things wrong about how I've implemented my solution.  It works for me though.  I'd love if someone who was more skilled took the idea and ran with it.
Get the Code!


No comments:

Post a Comment