I’m coding an application in Python with TKinter and I’m having this problem where the contents of portions of a scrollregion that should be invisible are being displayed.
I’ve built the following test code as a demonstration (modified only slightly from https://blog.teclado.com/tkinter-scrollable-frames/):
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
array=[]
def ResizeImage(image,new_size=(300,500)):
tempImage=Image.open(image)
card=tempImage.resize(new_size) #Don't re-use variable for somereason, and do in extra lines? Test later.
return ImageTk.PhotoImage(card)
root = tk.Tk()
container = ttk.Frame(root)
canvas = tk.Canvas(container)
scrollbar = ttk.Scrollbar(container, orient="vertical", command=canvas.yview)
scrollable_frame = ttk.Frame(canvas)
scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(
scrollregion=canvas.bbox("all")
)
)
canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)
for i in range(50):
array.append(ResizeImage("C:/Users/Fred/Desktop/Frederick/python projects/junk/Ballroom_Dance.png"))
if i%2:
y=ttk.Label(root, image=array[-1])
y.pack(in_=scrollable_frame)
x=ttk.Label(root, text="Sample scrolling label")
x.pack(in_=scrollable_frame)
else:
y=ttk.Label(scrollable_frame, image=array[-1])
y.pack()
ttk.Label(scrollable_frame, text="Sample scrolling label").pack()
container.pack()
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
root.mainloop()
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
root.mainloop()
What I see is that when a Label is a child of the scrollable frame everything works normally, but when the same Label is instead a child of root being placed with y.pack(in_=scrollable_frame)
the items are visible even when they shouldn’t be, although the scrolling otherwise functions fine.
In my actual program I need the widgets being placed in the scrollable frame to be nearly top-level, because the drag and drop implementation I’m using only works when the target shares an ancestor with the object to be dropped. Is there a way I can keep these widgets children of root but make them vanish correctly when scrolling? If not, is there another way to enable drag-and-drop between distantly related scrollable frames that only share some much higher-level ancestor?
nope noper is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1