0

I've been fighting this all day and I finally have a workable solution, which I'm hoping I don't get torn apart for. I was trying to make a window that allows me to scroll through multiple records, the only thing I have found is an old post on stackoverflow (originally like 2010, but he updated the code in 2018) that allows you to attach a frame to a canvas to scroll through all widgets on the frame.

The code below works, but I'm wondering how I change the size of the canvas. This seems to leave a line on the right side of the window that I believe is the edge of the canvas, and it doesn't fit it to the window, even with the canvas set to fill both and expand true. Is there something I am missing?

import tkinter as tk
import tkinter.ttk as ttk
        
def addNewCqrs():
    backEndCqrs = []
    frontEndCqrs = [[65435213245, 6543,52143, 65463543,654654, 6546354, 654654, 654654, 654654, 654654, 654654, 654654, 654654, 654654, 654654, 654654],[65435213245, 6543,52143, 65463543,654654, 6546354, 654654, 654654, 654654, 654654, 654654, 654654, 654654, 654654, 654654, 654654],[65435213245, 6543,52143, 65463543,654654, 6546354, 654654, 654654, 654654, 654654, 654654, 654654, 654654, 654654, 654654, 654654]]
    backEndIds = []
    newCqrs = []

    for cqr in backEndCqrs:
        backEndIds.append(cqr[0])

    for cqr in frontEndCqrs:
        if cqr[0] in backEndIds:
            continue
        newCqrs.append(cqr)

    window = tk.Tk()

    canvas = tk.Canvas(window, borderwidth=0, background='blue')
    canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

    frame = tk.Frame(master=canvas, relief=tk.RAISED, borderwidth=1, background='red')
    frame.grid(row=0, column=0, sticky=tk.NSEW)

    scroll = ttk.Scrollbar(master=window, command = canvas.yview)
    canvas.configure(yscrollcommand=scroll.set)
    scroll.pack(side=tk.RIGHT, fill=tk.Y)

    label = ttk.Label(master=frame)
    label.pack(fill=tk.BOTH, side=tk.TOP, expand=True)

    button = ttk.Button(master=frame, text='Exit', command=window.destroy)

    if len(newCqrs) == 0:
        label.config(text="We didn't find any new CQR's")
        button.pack(fill=tk.BOTH, side=tk.TOP)
        return
        
    label.config(text="We have added the following CQR's")

    for cqr in newCqrs:
        cqrText = (f'CQR {cqr[0]}\n'
                   f'Start time:            {cqr[1]}\n'
                   f'Completion time:       {cqr[2]}\n'
                   f'Email:                 {cqr[3]}\n'
                   f'Name:                  {cqr[4]}\n'
                   f'Dealer:                {cqr[5]}\n'
                   f'Customer:              {cqr[6]}\n'
                   f'Date reported:         {cqr[7]}\n'
                   f'Order number:          {cqr[8]}\n'
                   f'Invoice number:        {cqr[9]}\n'
                   f'Serial number:         {cqr[10]}\n'
                   f'Failed part number:    {cqr[11]}\n'
                   f'Causal part number:    {cqr[12]}\n'
                   f'Part Description:      {cqr[13]}\n'
                   f'Defect observed:       {cqr[14]}\n'
                   f'Files:                 {cqr[15]}\n')

        label = ttk.Label(master=frame, text=cqrText, wraplength=380, justify=tk.LEFT)
        label.pack(fill=tk.BOTH, side=tk.TOP)

    button.pack(fill=tk.BOTH, side=tk.TOP)

    canvas.create_window((0,0), window=frame, anchor=tk.NW)
    frame.bind("<Configure>", lambda event, canvas=canvas: onFrameConfigure(canvas))
    
def onFrameConfigure(canvas):
    canvas.configure(scrollregion=canvas.bbox('all'))

addNewCqrs()
  • _"I'm wondering how I change the size of the canvas."_ - when I run the code the canvas fills the window. Are you sure you want to make the canvas bigger, rather than making the inner frame bigger? – Bryan Oakley Feb 01 '23 at 21:42
  • Sorry @BryanOakley, I tried to quickly remove some unnecessary dependencies and move it over and I shouldn't have done that. It was actually also missing the import statements and function call. It works on my end now though. – Tyler Willke Feb 01 '23 at 21:47
  • @BryanOakley I'm not sure which part it is I guess, there is a line along the right side of the data, and I'm not sure how to size that to fill the available window space. – Tyler Willke Feb 01 '23 at 21:49
  • The right-most widget is the scrollbar, so the right side of the window should not be part of the canvas. Do you mean the left side of the scrollbar actually? If it is, then try setting `highlightthickness=0` when creating the canvas. Also you don't need to (or should not) call `frame.grid(...)` because it is override by the line `canvas.create_window(...)`. – acw1668 Feb 02 '23 at 03:02
  • @acw1668 I got the basic structure out of a 12 year old post of Bryan's on how to get the scrollbar working on a canvas and apparently added that out of habit. – Tyler Willke Feb 02 '23 at 16:47
  • I figured out my problem here as well, the code I wrote called to set the frame borderwidth to 1 which is the line I was seeing, I don't know why I was so blind to seeing that in my code, but I was. To @BryanOakley 's point, I was actually seeing an issue with the frame being too small. I thought the window was oversized to the canvas.I think the answer you posted here is actually what I'm looking for, does that seem like the right direction? https://stackoverflow.com/a/29319974/17390391 – Tyler Willke Feb 02 '23 at 16:50

0 Answers0