1

I have been looking at various sources but to no avail.

In my tkinter window, I have running Labels which start with "start" to 1 and all the way to 100. I have two problems:

  1. My labels are not stretching out in the Y direction even though fill=tk.Y is called (for self.firstlabel.pack and x.pack), as evidenced by the green background. Why is this happening?

  2. I've also tried to get the canvas height by first calling self.update() and then printing out the canvas height using print(self.canvas.winfo_height()). However the canvas height is still 1. Why is this the case?

Thank you all in advance for your answers!

import tkinter as tk

class Test(tk.Tk):

    def __init__(self, tasks=None):
        super().__init__()

        self.title("Test")

        # setting up container
        container = tk.Frame(self, background="bisque")
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)
        container.grid(row=0, column=0, sticky=(tk.N, tk.S, tk.E, tk.W))

        container.grid_columnconfigure(0, weight=1)
        container.grid_rowconfigure(0, weight=3)
        container.grid_rowconfigure(1, weight=1)

        # two frames in container, container1 for labels, container2 for textbox
        self.container1 = tk.Frame(container, background="yellow")
        self.container2 = tk.Frame(container, background="blue")
        self.container1.grid(row=0, sticky=(tk.N, tk.S, tk.E, tk.W))
        self.container2.grid(row=1, sticky=(tk.N, tk.S, tk.E, tk.W))

        self.canvas = tk.Canvas(self.container1, borderwidth=0, background="green")
        self.frameinsidecanvas = tk.Frame(self.canvas, background="pink")
        self.canvas.pack(fill="both", expand=True)
        self.frameinsidecanvas.pack(fill="both", expand=True)

        self.update()
        print(self.canvas.winfo_height())

        # setup scrollbar
        self.horizontalscrollbar = tk.Scrollbar(self.container1, orient="horizontal", command=self.canvas.xview)
        self.canvas.configure(xscrollcommand=self.horizontalscrollbar.set)
        self.horizontalscrollbar.pack(side="bottom", fill="x")

        self.canvas.create_window((0, 100), window=self.frameinsidecanvas, anchor="w")

        self.textbox = tk.Text(self.container2, height=1)
        self.textbox.pack(fill="both", expand=True)

        # creating the instructional label
        self.firstlabel = tk.Label(self.frameinsidecanvas, text="Start")
        # self.tasks.append(self.firstlabel)

        self.firstlabel.pack(side="left", fill=tk.Y, expand=True)

        # showing the labels
        for labels in range(0,100):
            x = tk.Label(self.frameinsidecanvas, text=str(labels))
            x.pack(side=tk.LEFT, fill=tk.Y, expand=True)

        self.bind("<Configure>", self.on_frame_configure)

    def on_frame_configure(self, event=None):
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

if __name__ == "__main__":
    test = Test()
    test.wm_geometry("1100x500")
    test.mainloop()

miniarcher
  • 21
  • 2
  • You want to display the labels in column or that each label had the height of the canvas? – Mat.C Jan 11 '20 at 11:51
  • @Mat.C I want to stretch each label to the height of the canvas – miniarcher Jan 11 '20 at 11:59
  • Does this answer your question? [Tkinter: How to get frame in canvas window to expand to the size of the canvas?](https://stackoverflow.com/questions/29319445/tkinter-how-to-get-frame-in-canvas-window-to-expand-to-the-size-of-the-canvas) – stovfl Jan 11 '20 at 18:12

2 Answers2

0

The problem is that at the start of the program the canvas height is equal to 1. After that the tkinter window is rendered it changes the value.

You can simply bind a canvas listner to <Configure> for get when the height changes and after modify the inner fram of consequence.

import tkinter as tk
# You want to display the labels in column or that each label had the height of the canvas?
class Test(tk.Tk):

    def __init__(self, tasks=None):
        super().__init__()
        self.canvas_width = None

        self.title("Test")

        # setting up container
        container = tk.Frame(self, background="bisque")
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)
        container.grid(row=0, column=0, sticky=(tk.N, tk.S, tk.E, tk.W))

        container.grid_columnconfigure(0, weight=1)
        container.grid_rowconfigure(0, weight=3)
        container.grid_rowconfigure(1, weight=1)

        # two frames in container, container1 for labels, container2 for textbox
        self.container1 = tk.Frame(container, background="yellow")
        self.container2 = tk.Frame(container, background="blue")
        self.container1.grid(row=0, sticky=(tk.N, tk.S, tk.E, tk.W))
        self.container2.grid(row=1, sticky=(tk.N, tk.S, tk.E, tk.W))

        self.canvas = tk.Canvas(self.container1, borderwidth=0, background="black")

        self.frameinsidecanvas = tk.Frame(self.canvas, background="pink")
        self.canvas.pack(fill="both", expand=True)
        self.frameinsidecanvas.pack(fill="both", expand=True)

        # setup scrollbar
        self.horizontalscrollbar = tk.Scrollbar(self.container1, orient="horizontal", command=self.canvas.xview)
        self.canvas.configure(xscrollcommand=self.horizontalscrollbar.set)
        self.horizontalscrollbar.pack(side="bottom", fill="x")

        self.canvas.create_window((0, 100), window=self.frameinsidecanvas, anchor="w")

        self.textbox = tk.Text(self.container2, height=1)
        self.textbox.pack(fill="both", expand=True)

        # creating the instructional label
        self.firstlabel = tk.Label(self.frameinsidecanvas, text="start")
        # self.tasks.append(self.firstlabel)

        self.firstlabel.pack(side="left", fill=tk.Y)

        # showing the labels
        for label_index in range(0, 10):
            x = tk.Label(self.frameinsidecanvas, text=label_index)
            x.pack(side=tk.LEFT, fill=tk.Y, expand=True)

        self.canvas.bind("<Configure>", self.update_width)

    def update_width(self, e):
        self.canvas_width = self.canvas.winfo_width()
        self.canvas_height = self.canvas.winfo_height()
        self.firstlabel.configure(height=self.canvas_height)
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

if __name__ == "__main__":
    test = Test()
    test.wm_geometry("1100x500")
    test.mainloop()
Mat.C
  • 1,379
  • 2
  • 21
  • 43
0

For the first question,

If you want to fill the label widget, use firstlabel.pack(fill = 'x')

if you want to align the text on the left side, use firstlabel = tk.Label(frameinsidecanvas, text="Start", anchor = 'w') I hope you got the idea.

The below code will align the text on the left side and fill the label widget.

self.firstlabel = tk.Label(self.frameinsidecanvas, text="Start", anchor = 'w')
self.firstlabel.pack(fill=tk.Y, expand=True)
Vasigaran
  • 26
  • 2