Python Forum
[Tkinter] Resizing image inside Canvas (with Canvas' resize)
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Resizing image inside Canvas (with Canvas' resize)
#1
The situation is next:
- I'm resizing window;
- Canvas widget is resizing too;
- PhotoImage inside Canvas stays the same size as it was.
How can I make it resize with the other widgets?

My code:
import tkinter as tk
from tkinter import ttk as tktw
import time
import socket
 
 
class Window(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.geometry("640x480")
        self.minsize(width=640, height=480)
        self.fm = FrameMain(self, background="pink")
        self.fb = FrameBottom(self, background="lightblue")
        self.fl = FrameLeft(self.fm, background="yellow")
        self.fr = FrameRight(self.fm, background="green")
        self.fa = FrameAction(self.fr, background="orange")
        self.fc = FrameChat(self.fr, background="blue")
        self.tm = TopMenu(self)
        self.config(menu=self.tm)
        # self.ab = ActionBar(self.fa, width=0, height=0)
        # self.ai = ActionInfo(self.ab, width=0, height=0)
        # self.ab.add(self.ai, text="Info", state="normal")
        self.c = CanvasArea(self.fl, width=0, height=0)
 
 
class FrameMain(tk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(fill=tk.BOTH, expand=1)
 
 
class FrameLeft(tk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(fill=tk.BOTH, expand=1, side="left")
 
 
class CanvasArea(tk.Canvas):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(fill=tk.BOTH, expand=1)
 
 
class FrameRight(tk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(fill=tk.BOTH, expand=1, side="right")
 
 
class FrameChat(tk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(fill=tk.BOTH, expand=1, side="bottom")
 
 
class FrameAction(tk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(fill=tk.BOTH, expand=1, side="top")
 
 
class ActionBar(tktw.Notebook):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(expand=1, fill=tk.BOTH)
 
 
class ActionInfo(tk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(fill=tk.BOTH, expand=1)
 
 
class FrameBottom(tk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(fill=tk.BOTH)
        self.cb = ComboboxCommands(self, width=10, state="readonly")
        self.cl = CommandLine(self, relief="ridge", bd=2)
        self.bs = ButtonSend(self, text="Send", relief="ridge")
 
 
class ComboboxCommands(tktw.Combobox):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(side="left", fill=tk.BOTH)
 
 
class CommandLine(tk.Entry):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(side="left", fill=tk.BOTH, expand=1)
 
 
class ButtonSend(tk.Button):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(side="right")
 
 
class TopMenu(tk.Menu):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.add_cascade(label="Menu")
 
 
if __name__ == "__main__":
    w = Window()
 
    imgsrc = tk.PhotoImage(file="images/img.gif")
    img = w.c.create_image(0, 0, anchor="nw", image=imgsrc)
 
    w.mainloop()
[Image: photoimage.png]
Reply
#2
Bind an event to the canvas to get its size , use PIL to resize the image.
import tkinter as tk
from PIL import Image, ImageTk


class MainFrame(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.canvas = tk.Canvas(self)
        self.canvas.pack(fill=tk.BOTH, expand=1)
        self.canvas.bind("<Configure>", self.resize)
        self.img = ImageTk.PhotoImage(
            Image.open(r"gui\110px-Python-logo-notext.svg.png")
        )
        self.canvas_img = self.canvas.create_image(0, 0, anchor="nw", image=self.img)

    def resize(self, event):
        img = Image.open(r"gui\110px-Python-logo-notext.svg.png").resize(
            (event.width, event.height), Image.ANTIALIAS
        )
        self.img = ImageTk.PhotoImage(img)
        self.canvas.itemconfig(self.canvas_img, image=self.img)


if __name__ == "__main__":
    main_frame = MainFrame()
    main_frame.mainloop()
Reply
#3
Thank you for help!
I'm sorry for the late answer. The resize event gave me an idea of handling layout in my application, so I've managed to solve the problem with it either. I've used place() method to get the result I want, I'll post it later in the layout's thread.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyQt] Tutorial bug with PyQt6 canvas Mike88 5 1,003 Jan-02-2025, 10:37 PM
Last Post: Mike88
Question Using PIL to resize an image produces no image Calab 2 795 Oct-28-2024, 02:43 AM
Last Post: deanhystad
  [Tkinter] Can i draw more elements in a canvas? Yeti 2 1,710 Dec-14-2023, 04:46 PM
Last Post: deanhystad
  [Tkinter] COMPLEX! Transparent Canvas Linux AceScottie 7 4,032 Jun-21-2023, 06:44 PM
Last Post: AceScottie
  tkinter.TclError: can't invoke "canvas" command cybertooth 8 10,193 Feb-23-2023, 06:58 PM
Last Post: deanhystad
  Video in Canvas finndude 6 5,566 Oct-04-2022, 02:02 PM
Last Post: finndude
  [Tkinter] Transparent Canvas finndude 8 16,136 Oct-02-2022, 01:48 PM
Last Post: joe_momma
  [Tkinter] canvas size DPaul 2 8,448 May-04-2022, 12:34 PM
Last Post: DPaul
  [Tkinter] canvas image problem DPaul 4 10,457 Nov-24-2021, 07:06 AM
Last Post: DPaul
  [PyQt] Can't get MDIarea to resize automatically with Main Window JayCee 4 4,929 Aug-02-2021, 08:47 PM
Last Post: JayCee

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020