Reputation: 115
I have created a class that makes a Scrollable canvas with scrollbar in Tkinter:
class ScrollableFrame(ttk.Frame):
def __init__(self, container, *args, **kwargs):
super().__init__(container, *args, **kwargs)
self.canvas = tk.Canvas(self)
scrollbar = ttk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
self.scrollable_frame = ttk.Frame(self.canvas)
self.scrollable_frame.bind(
"<Configure>",
lambda e: self.canvas.configure(
scrollregion=self.canvas.bbox("all")
)
)
self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
self.canvas.configure(yscrollcommand=scrollbar.set)
self.canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
def scroll_to_end(self):
self.canvas.yview_moveto(1)
Then I created a frame in it and placed widgets in it:
root = tk.Tk()
frame = ScrollableFrame(root)
# Frame to place messages on
scrollable_frame = tk.Frame(frame.scrollable_frame, height=80, width=900)
scrollable_frame.pack()
img1 = ImageTk.Photo
Image(Image.open(r'./chat_bg.jpg'))
panel1 = tk.Label(scrollable_frame, image=img1)
panel1.place(x=0, y=0)
# Text box to send message
message_entry = tk.Entry(root, bg='grey')
message_entry.pack(side='bottom', fill='x')
message_entry.focus_set()
message_placing_height = 5 # Variable to specify the height where message to be placed
# Sending button
send_button = tk.Button(root, text="Send", activebackground="pink")
send_button.pack(side='bottom', anchor='ne')
#THIS LOOP IS ONLY FOR REFERENCE
#BUT IN REAL WIDGETS WILL BE PLACED ONE AFTER ANOTHER AFTER TIME INTERVALS
for i in range(20):
y = message_placing_height
msg_label = tk.Label(scrollable_frame, text='Hello World'+ str(i), fg="red", font="Times 12")
msg_label.place(x=170, y=y)
message_entry.delete(0, 'end')
message_placing_height += 25
scrollable_frame.configure(height=message_placing_height)
frame.pack()
# __MAIN__
root.mainloop()
This code places the background Image on the frame and as I scroll the frame eventually the image ends and background is white again.
I want the image to be static. To solve this I want the image to be placed on the canvas (and probably the frame should be transparent - correct me if I am wrong)
I placed the image on the canvas but image wasn't shown at all(Probably because frame was above the canvas)
Please help me.
Upvotes: 0
Views: 901
Reputation: 46786
You can chain another callback on <Configure>
event of frame.scrollable_frame
and move the background image inside that callback:
def on_scroll(event):
# get the canvas (x, y) of the top-left corner of current viewable area
x, y = frame.canvas.canvasx(0), frame.canvas.canvasy(0)
# move the background image
panel1.place(x=x, y=y)
frame.scrollable_frame.bind('<Configure>', on_scroll, '+') # chain another callback
Add the above code below the line panel1.place(x=0, y=0)
.
Upvotes: 2