canvas scrolling issue tkinter

2019-03-06 08:57发布

问题:

I have begun working on this file and I am trying to get the canvas with the majority of the widgets to scroll, but it isn't working. I think the problem is in the definition of height, width, and scroll region. But I haven't been able to get anything to work when I play around with those numbers. Here is the code:

from tkinter import *
from tkinter import ttk
from tkinter import filedialog

def work_area():
    #create GUI
    root = Tk()
    root.geometry("+800+300")
    root.title("FSCE Database")
    frame_main = ttk.Frame(root)
    frame_main.grid(column = 0, row = 0)

    #variables
    sort_by_var = StringVar()
    names_list = ()
    names_string = StringVar(value = names_list)
    FONT = ("TkDefaultFont", 11)

    father_name = StringVar()
    address = StringVar()
    city = StringVar()
    state = StringVar()
    home_phone = StringVar()
    cell_phone = StringVar()
    email = StringVar()
    num_people = StringVar()
    name_age = StringVar()
    campsite = StringVar()
    notes = StringVar()

    #populate
    #frame left
    frame_left = ttk.Frame(frame_main)
    frame_left.grid(column = 1, row = 1)

    SORT_BY_TEXT = ttk.Label(frame_left, text = "Sort By:", font = FONT)
    SORT_BY_TEXT.grid(column = 1, row = 1)

    SORT_BY = ttk.Combobox(frame_left, textvariable = sort_by_var, font = FONT, width = 8)
    SORT_BY.grid(column = 2, row = 1)
    SORT_BY["values"] = ("Name", "# People", "Date")

    NAMES = Listbox(frame_left, listvariable = names_string, font = FONT, height = 10, relief = "ridge")
    NAMES.grid(column = 1, columnspan = 2, row = 2, sticky = ("E, W"))

    ADD = ttk.Button(frame_left, text = "Add", command = None)
    ADD.grid(column = 1, row = 3)

    REMOVE = ttk.Button(frame_left, text = "Remove", command = None)
    REMOVE.grid(column = 2, row = 3, sticky = ("E"))

    SCROLLBAR = ttk.Scrollbar(frame_left, orient = VERTICAL, command = NAMES.yview)
    SCROLLBAR.grid(column = 3, row = 2, sticky = ("N, S"))
    NAMES.configure(yscrollcommand = SCROLLBAR.set)

    for child in frame_left.winfo_children():
        child.grid_configure(padx = 5, pady = 5)

    #right side
    canvas = Canvas(frame_main, height = 200, width = 300, scrollregion = (0, 0, 300, 500))
    canvas.grid(column = 2, row = 1)

    SCROLLBAR_2 = ttk.Scrollbar(frame_main, orient = VERTICAL)
    SCROLLBAR_2.grid(column = 3, row = 1, sticky = ("N, S"))
    canvas.configure(yscrollcommand = SCROLLBAR_2.set)
    SCROLLBAR_2.configure(command = canvas.yview)

    F_N_L = ttk.Label(canvas, text = "Father/Guardian:", font = FONT)
    F_N_L.grid(column = 1, row = 1, sticky = ("E"))    
    F_N_E = ttk.Entry(canvas, textvariable = father_name, font = FONT, width = 20)
    F_N_E.grid(column = 2, columnspan = 3, row = 1, sticky = ("W"))

    A_L = ttk.Label(canvas, text = "Address:", font = FONT)
    A_L.grid(column = 1, row = 2, sticky = ("E"))    
    A_E = ttk.Entry(canvas, textvariable = address, font = FONT, width = 30)
    A_E.grid(column = 2, columnspan = 3, row = 2, sticky = ("W"))

    C_L = ttk.Label(canvas, text = "City:", font = FONT)
    C_L.grid(column = 1, row = 3, sticky = ("E"))
    C_E = ttk.Entry(canvas, textvariable = city, font = FONT, width = 15)
    C_E.grid(column = 2, row = 3, sticky = ("W"))

    S_L = ttk.Label(canvas, text = "State:", font = FONT)
    S_L.grid(column = 3, row = 3, sticky = ("E"))
    S_E = ttk.Entry(canvas, textvariable = state, font = FONT, width = 5)
    S_E.grid(column = 4, row = 3, sticky = ("W"))

    E_L = ttk.Label(canvas, text = "Email:", font = FONT)
    E_L.grid(column = 1, row = 4, sticky = ("E"))
    E_E = ttk.Entry(canvas, textvariable = email, font = FONT, width = 25)
    E_E.grid(column = 2, columnspan = 2, row = 4, sticky = ("W"))

    HP_L = ttk.Label(canvas, text = "Home Phone:", font = FONT)
    HP_L.grid(column = 1, row = 5, sticky = ("E"))
    HP_E = ttk.Entry(canvas, textvariable = home_phone, font = FONT, width = 12)
    HP_E.grid(column = 2, row = 5, sticky = ("W"))

    CP_L = ttk.Label(canvas, text = "Cell Phone:", font = FONT)
    CP_L.grid(column = 1, row = 6, sticky = ("E"))
    CP_E = ttk.Entry(canvas, textvariable = cell_phone, font = FONT, width = 12)
    CP_E.grid(column = 2, row = 6, sticky = ("W"))

    NP_L = ttk.Label(canvas, text = "# Of People:", font = FONT)
    NP_L.grid(column = 1, row = 7, sticky = ("E"))
    NP_E = Spinbox(canvas, from_ = 1, to = 10, increment = 1, textvariable = num_people, font = FONT, width = 2)
    NP_E.grid(column = 2, row = 7, sticky = ("W"))

    #bottom frame
    frame_bottom = ttk.Frame(canvas)
    frame_bottom.grid(column = 1, columnspan = 5, row = 8)

    C_NAMES_L = Listbox(frame_bottom, listvariable = None, font = FONT, width = 12, height = 4, relief = "ridge")
    C_NAMES_L.grid(column = 1, row = 1, rowspan = 3)

    SCROLLBAR_3 = ttk.Scrollbar(frame_bottom, orient = VERTICAL, command = C_NAMES_L.yview)
    SCROLLBAR_3.grid(column = 2, row = 1, rowspan = 3, sticky = ("N, S"))
    C_NAMES_L.configure(yscrollcommand = SCROLLBAR_3.set)

    NA_L = ttk.Label(frame_bottom, text = "Name & Age:", font = FONT)
    NA_L.grid(column = 3, columnspan = 2, row = 1)
    NA_E = ttk.Entry(frame_bottom, textvariable = name_age, font = FONT, width = 12)
    NA_E.grid(column = 3, columnspan = 2, row = 2)

    ADD_2 = ttk.Button(frame_bottom, text = "Add", command = None)
    ADD_2.grid(column = 3, row = 3)
    REMOVE_2 = ttk.Button(frame_bottom, text = "Remove", command = None)
    REMOVE_2.grid(column = 4, row = 3) 

    for child in frame_bottom.winfo_children():
        child.grid_configure(padx = 5, pady = 5)

    #back to canvas
    CN_L = ttk.Label(canvas, text = "Campsite #:", font = FONT)
    CN_L.grid(column = 1, row = 9, sticky = ("E"))
    CN_E = ttk.Entry(canvas, textvariable = campsite, font = FONT, width = 5)
    CN_E.grid(column = 2, row = 9, sticky = ("W"))

    N_L = ttk.Label(canvas, text = "Notes:", font = FONT)
    N_L.grid(column = 2, row = 10)
    N_E = ttk.Entry(canvas, textvariable = notes, font = FONT, width = 40)
    N_E.grid(column = 1, columnspan = 4, row = 11, sticky = ("E"))


    for child in canvas.winfo_children():
        child.grid_configure(padx = 5, pady = 5)

    for child in frame_main.winfo_children():
        child.grid_configure(padx = 5, pady = 5)

    root.mainloop()
work_area()

回答1:

If you want to be able to scroll widgets that are on the canvas, you can't pack or grid those widgets on the canvas. You need to use the create_window method to embed the widget in the canvas.

The typical pattern is to use pack or grid to arrange widgets in a frame, then use create_window to add just that single frame to the canvas.