RKonos
RKonos

Reputation: 49

How to prevent flickering of the window when resizing canvas/frame?

The code seen below is technically functional and able display a test set of labels in a frame within a canvas which is then used to scroll through the items.

My issue is that when I run the code and try to scroll through the values the window (not sure which) will repeatedly flash due to the canvas or frame/labels within it trying to resize itself.

This code is part of a larger program I'm working on but I've stripped everything out that doesn't need to be there for the troubleshooting.

My testing approach


  1. Ran the code and inputted a random string into the text box then pressed search
  2. resized the window by dragging down to allow for easier scrolling
  3. noticed the issue with the the window flashing with the canvas wanting to resize itself. After some scrolling the canvas will extend itself to the horizontal size it wants to be and then the list will be scrolled through just fine
  4. compress the window horizontally to where the canvas is forced to resize smaller
  5. notice that the list of items is able to be scrolled through just fine
  6. expand the window horizontally well out past the point where the canvas wants to resize itself to
  7. again notice the flashing until it resizes itself and then its fine
  8. clearing the canvas by removing everything from the text box and pressing search then redoing the steps above nets the same results so there doesn't seem to be an issue there.

My conclusion for what could be wrong


I am no expert in the field of using tkinter but based on my testing all I could think is that somehow I have limited the size canvas whist not limiting frame or labels within this causing some kind of issue between them. If its not this, one thing I do know is that the canvas doesn't like its starting sizing and really wants to change for some reason. I guess I've just been looking at the code too long that the issue has probably concealed itself in plain view and I need another pair of eyes to set me strait.

from tkinter import *

# colors and other variables
color_dark_grey = "#2C2C2C"  # background color
color_light_grey = "#424242"  # frame colors
pad_outer = 10
fontsize = 12
results_thickness = 100

# main window stuff
window = Tk()  # creates the window
window.title("My Engineering Glossary")
window.configure(background=color_dark_grey)


# Puts stuff into the search results area to test it
def print_search():
    for i in range(0, 20):
        Label(frm_results_inner, text="col1 text", bg="grey").grid(row=i, column=1)
        Label(frm_results_inner, text="col 2, longer text", bg="magenta").grid(row=i, column=2)
        Label(frm_results_inner, text="col 3, a little longer still", bg="blue").grid(row=i, column=3)


# is purely to get the scrollbar to work. Leave it alone
def scroll_results_event(event):    # for search results
    canv_results.configure(scrollregion=canv_results.bbox("all"))


# will check what has been inputted into the text box to determine what to print
def check_input():
    txt = txt_search.get()
    if txt == "":          # when there is nothing in the text box
        frm_results.pack_forget()      # hides the canvas with search results
        lab_results.pack(padx=pad_outer / 2, pady=pad_outer / 4)    # shows the no search frame
    else:                              # when there is something in the text box
        lab_results.pack_forget()  # hides the frame for no search

        # packs in the scrolbar, canvas, and wrapping frame
        frm_results.pack(fill="both", expand=True)
        # calls function to print out results
        print_search()


# ============================================ NOW THE MAIN CODE BODY BEGINS ===========================================


# ---------------------------area for text input to search stuff---------------------------
# the frame for the accompanying stuff to go in
frm_input = Frame(window, bg=color_light_grey)
frm_input.pack(pady=pad_outer, fill="both")

# lable to indicate search region
lab_search = Label(frm_input, text="What do you want to search for?", bg=color_light_grey, fg='white',
                   font=("", fontsize))
lab_search.pack(padx=pad_outer / 2, pady=pad_outer / 4)

# text box to get user input
txt_search = Entry(frm_input, bg=color_light_grey, fg="white")
txt_search.pack(fill="both", expand=True, side="left", padx=pad_outer / 4, pady=pad_outer / 4)

# button to begin searching. Calls the "check_input" function that starts the process of printing results
btn_search = Button(frm_input, text="Search", bg=color_light_grey, fg="white", activebackground=color_dark_grey,
                    activeforeground="white", command=check_input)
btn_search.pack(side="right", padx=pad_outer / 4, pady=pad_outer / 6)


# ---------------------------area for search results---------------------------
# wrapper frame for everything going into the search results area
frm_results = Frame(window, bg=color_light_grey)
frm_results.pack(fill="both", expand=True, ipadx=results_thickness)

# lable to indicate nothing has been searched. will be packed in with the check_input() function
lab_results = Label(frm_results, text="Nothing has been searched.",
                    bg=color_light_grey, fg='white', font=("", fontsize))

# the outer frame that will hold the actual list of results
frm_results = Frame(frm_results, bg=color_light_grey)
# lable indicating search results are ready
lbl_canv_results = Label(frm_results, text="Test Search results", bg=color_light_grey, fg='white', font=("", fontsize))
# the canvas that will enable the possibility to scroll through the various search results
canv_results = Canvas(frm_results, bg=color_light_grey)
# frame in which the results will be listed
frm_results_inner = Frame(canv_results, bg=color_light_grey)
# scroll bar that will can scroll through results shown in frm_results_inner on the canvas
srlb_results = Scrollbar(canv_results, orient="vertical", command=canv_results.yview)

# configures the canvas to include a scrolling command linked to the scrollbar
canv_results.configure(yscrollcommand=srlb_results.set)

# pack in everything for the search results. They won't show up because
lbl_canv_results.pack(padx=pad_outer / 2, pady=pad_outer / 4)
srlb_results.pack(side="right", fill="y")
canv_results.pack(fill="both", expand=True, padx=pad_outer / 2, pady=pad_outer / 4)

# creates a window in which the frame is placed. This allows the frame to be scrolled through
canv_results.create_window((1, 1), window=frm_results_inner, anchor='nw')

# calls the function that will actually enable the scrolling. I don't understand why this works so leave it alone
frm_results_inner.bind("<Configure>", scroll_results_event)

check_input()   # will look at input in the text box to display first item


window.mainloop()  # keeps the window open

Upvotes: 2

Views: 885

Answers (1)

RKonos
RKonos

Reputation: 49

@acw1668 comment fixed the issue I was having. Cheers

You use wrong parent (canv_results) on srlb_results. Use frm_results instead.

Upvotes: 2

Related Questions