调整画布/框架大小时如何防止窗口闪烁?

时间:2020-06-15 22:12:57

标签: python python-3.x tkinter tkinter-canvas

以下代码在技术上可以正常工作,并且能够在画布中的框架中显示一组测试标签,然后将其用于滚动项目。

我的问题是,当我运行代码并尝试滚动浏览值时,由于其中的画布或框架/标签试图调整自身大小,窗口(不确定哪个)将反复闪烁。

此代码是我正在开发的一个较大程序的一部分,但是我剔除了不需要进行故障排除的所有内容。

我的测试方法


  1. 运行代码,然后在文本框中输入随机字符串,然后按搜索
  2. 通过向下拖动来调整窗口大小,以便于滚动
  3. 注意到该问题,即窗口闪烁并希望调整自身大小的画布。进行一些滚动之后,画布会自动扩展到想要的水平尺寸,然后列表就会滚动通过
  4. 将窗口水平压缩到强制将画布调整为较小尺寸的位置
  5. 请注意,项目列表可以正常滚动
  6. 水平扩展窗口,使其超出画布想要调整大小的点
  7. 再次注意闪烁,直到它调整大小,然后变好
  8. 通过从文本框中删除所有内容并按搜索,然后重做上面的步骤来清除画布,可以得到相同的结果,因此似乎没有问题。

我对可能出问题的结论


我不是使用tkinter领域的专家,但根据我的测试,我可以想到的是,我以某种方式限制了画布的尺寸,而没有限制框架或标签,从而在他们之间造成了某种问题。如果不是这样,我确实知道一件事,那就是画布不喜欢它的开始调整大小,并且确实出于某种原因想要更改。我想我一直在看代码太久了,这个问题很可能已隐藏在普通视图中,我需要另一双眼睛让我陷入困境。

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

1 个答案:

答案 0 :(得分:1)

@ acw1668评论解决了我遇到的问题。干杯

您对srlb_results使用了错误的父(canv_results)。请改用frm_results。

相关问题