0

Tkinter resizablecanvas class does not resize all the widgets and it is malfunctioning. The canvas keeps on growing. The Canvas keeps going in size. What I am trying to achieve is that I need all the widgets to be resized when I maximize the window. My code is as follows

from tkinter import *
from tkinter import ttk

class ResizingCanvas(Canvas):
    def __init__(self,parent,**kwargs):
        Canvas.__init__(self,parent,**kwargs)
        self.bind("<Configure>", self.resize)
        self.height = self.winfo_reqheight()
        self.width = self.winfo_reqwidth()

    def resize(self,event):
        wscale = float(event.width)/self.width
        hscale = float(event.height)/self.height
        self.width = event.width
        self.height = event.height
        self.config(width=self.width, height=self.height)
        self.scale("all",0,0,wscale,hscale)
        print (self.width, self.height)


class Test(Frame):
    def Widgets(self):
        self.tabcontrol = ttk.Notebook(self)

        self.mainframe = Frame(self)
        self.tabcontrol.add(self.mainframe, text = "TAB-1")
        self.tabcontrol.pack(fill= "both", expand = YES)

        self.canvasframe = Frame(self.mainframe)
        self.canvasframe.grid(row=0, column = 0)

        self.canvas = ResizingCanvas(self.canvasframe)
        self.canvas.grid(row=0, column = 0)

        self.widgetframe = Frame(self.canvasframe)
        self.canvas.create_window(100,100, window = self.widgetframe)

        self.LABEL = Label(self.widgetframe, text = "LABEL-1")
        self.LABEL.grid(row=1, column= 1)

        self.BUTTON = Button(self.widgetframe, text = "BUTTON-1")
        self.BUTTON.grid(row=1, column= 2)

        self.widgetframe.update_idletasks()


    def __init__(self,initial):
        super(Test, self).__init__(initial)
        self.grid()
        self.Widgets()


root = Tk()
Software = Test(root)
root.mainloop()

Could someone please help me ? Thank you !

  • When you configure the width and height (`self.config(width=..., height=...)`), you cause another `` event, which changes the width and height, which causes another `` event, and so on until the program crashes. – Bryan Oakley Jan 30 '19 at 20:03
  • Removing the (self.config(width=..., height=...)) line stops the program canvas from getting resized when the event is triggered. How can all the widgets be resized appropriately when the maximize button is clicked ? –  Jan 30 '19 at 20:19
  • It's a bit unclear what you're asking, but for a first step you should probably learn how to use the `sticky` option when using `grid`, and learn about row and column weights. – Bryan Oakley Jan 30 '19 at 20:42
  • If I click the maximize button, then the canvas size must get reconfigured according to the size of my laptop screen. Like it is given in the following example:https://stackoverflow.com/questions/22835289/how-to-get-tkinter-canvas-to-dynamically-resize-to-window-width –  Jan 30 '19 at 20:46

1 Answers1

0

If I understand your requirements, what you want is for the canvas to fill the window even when the window resizes. Tkinter can do that automatically, if you use the proper grid, pack, or place options.

You've made this very difficult with your choice of using multiple layers of frames, and the use of grid instead of pack. If you're only putting one widget in another (the tab control in the root window, the canvas in the canvas frame, etc), using pack instead of grid will require fewer lines of code.

The following code illustrates how I would rewrite your code to eliminate some of the extra frames, and to force the notebook tab and the canvas to automatically grow with the root window. I've also added a color to the canvas so that it's easier to visualize.

Notice the use of pack instead of grid when adding self to the root window, and when adding the canvas to the frame. You can use grid if you wish, but it requires that you also configure rows and columns to have a non-zero weight. That's easy to do, but it takes three lines of code for grid and one line for pack when you have such a simple layout.

from tkinter import *
from tkinter import ttk

class Test(Frame):
    def Widgets(self):
        self.tabcontrol = ttk.Notebook(self)

        self.mainframe = Frame(self)
        self.tabcontrol.add(self.mainframe, text = "TAB-1")
        self.tabcontrol.pack(fill= "both", expand = YES)

        self.canvas = Canvas(self.mainframe, background="bisque")
        self.canvas.pack(fill="both", expand=True)

        self.widgetframe = Frame(self.canvas)
        self.canvas.create_window(100,100, window = self.widgetframe)

        self.LABEL = Label(self.widgetframe, text = "LABEL-1")
        self.LABEL.grid(row=1, column= 1)

        self.BUTTON = Button(self.widgetframe, text = "BUTTON-1")
        self.BUTTON.grid(row=1, column= 2)        

    def __init__(self,initial):
        super(Test, self).__init__(initial)
        self.pack(fill="both", expand=True)
        self.Widgets()


root = Tk()
Software = Test(root)
root.mainloop()
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685