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
  how do i find the canvas location of an object? gr3yali3n 10 6,749 Feb-21-2024, 02:00 AM
Last Post: caylakling
  [Tkinter] Can i draw more elements in a canvas? Yeti 2 609 Dec-14-2023, 04:46 PM
Last Post: deanhystad
  [Tkinter] COMPLEX! Transparent Canvas Linux AceScottie 7 1,624 Jun-21-2023, 06:44 PM
Last Post: AceScottie
  tkinter.TclError: can't invoke "canvas" command cybertooth 8 5,772 Feb-23-2023, 06:58 PM
Last Post: deanhystad
  Video in Canvas finndude 6 2,911 Oct-04-2022, 02:02 PM
Last Post: finndude
  [Tkinter] Transparent Canvas finndude 8 9,640 Oct-02-2022, 01:48 PM
Last Post: joe_momma
  [Tkinter] canvas size DPaul 2 5,675 May-04-2022, 12:34 PM
Last Post: DPaul
  [Tkinter] canvas image problem DPaul 4 6,255 Nov-24-2021, 07:06 AM
Last Post: DPaul
  [PyQt] Can't get MDIarea to resize automatically with Main Window JayCee 4 3,395 Aug-02-2021, 08:47 PM
Last Post: JayCee
  [Tkinter] image inside button rwahdan 4 6,882 Jul-12-2021, 08:49 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

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