1

I have the following code with the scrollable frame working perfecty fine (thanks to all other posters here). Now one thing is puzzling me: how do I manage the code to open the app window with such size, that it fits everything in it?

Whatever I do or try, the app window always opens with some default size (I guess its the canvas default size) instead of fitting to its content. In the example below I added 20 text labels to show the behavior. The created window fits only 14 of these labels. The others are there and its scrollable, but I want the startup window to fit everything right away.

I want to avoid setting a fixed size for the tk() window in the first place. I honestly don't fully understand the code I collected from the other threads, but everything works except for the issue I just described.

import tkinter as tk
from tkinter import ttk

class mainWindow():
    ''' Master class of the gui window. '''
    def __init__(self,appName):
        self.window = tk.Tk()
        self.window.title(appName)

        self.canvas = tk.Canvas(self.window)
        self.GlobalContentFrame = tk.Frame(self.canvas, background="#ffffff")
        self.vsb = tk.Scrollbar(self.window, orient="vertical", command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.vsb.set)

        self.vsb.pack(side=tk.RIGHT, fill="y")
        self.canvas.pack(side=tk.LEFT, fill="both",expand=1)
        self.canvas.create_window((1,1), window=self.GlobalContentFrame, anchor="nw",tags="self.GlobalContentFrame")

        self.GlobalContentFrame.bind("<Configure>", self.onFrameConfigure)
        self.canvas.bind("<Configure>", self.onCanvasConfigure)

        for p in range(20):
            label = ttk.Label(self.GlobalContentFrame,text="test")
            label.grid(column=0,row=p,sticky=tk.EW)

        self.window.mainloop()

    def onCanvasConfigure(self,event):
        w,h = event.width, event.height
        natural = self.GlobalContentFrame.winfo_reqwidth()
        self.canvas.itemconfigure("inner", width= w if w>natural else natural)
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

    def onFrameConfigure(self, event):
            '''Reset the scroll region to encompass the inner frame'''
            self.canvas.configure(scrollregion=self.canvas.bbox("all"))

appWin = mainWindow("test")
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
Atd
  • 21
  • 4
  • ***startup window to fit everything***: The soulution is to set the size of `Canvas` to the size of `GlobalContentFrame` at **only the first** ``. – stovfl Jun 13 '20 at 14:26
  • Could you tell me what part of the code would have to be omitted? Also what I do not understand, how does the code even show anything without using .pack() on the GlobalContentFrame? – Atd Jun 14 '20 at 08:44
  • ***what part of the code would have to be omitted?***: `.bind("` event***. Read [Tkinter window in canvas doesn't fill its parent in height](https://stackoverflow.com/a/44635263/7414759). ***without using `.pack()`***: `.create_window(...` does the layout. – stovfl Jun 14 '20 at 09:13
  • I tried with your suggestion but am still not sure what "the first" configure event is. From what I understand it is always executed when the user changes the window size for example (but creating the window doesn't seem to be an event?). Then I can only execute it never or always?! However, I found a solution by getting the `GlobalContentFrame` dimensions and sneaking in `window.geometry()` right there before the mainloop. – Atd Jun 16 '20 at 10:52
  • ***only execute it never or always?!***: You have to set a flag, eg.g `GlobalContentFrame._first_configure = True`, in event callback do `if event.widget._first_configure: ; event.widget._first_configure = False ; # set size`. – stovfl Jun 16 '20 at 12:21

0 Answers0