I have made a user interface but my scrollbar is not working. it is working if i add content statically but when i add frames from button click then it adds new frame but not scrolling to view bottom content or we can say the scroll bar is disabled.
Here is my code:
import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
root = tk.Tk()
root.grid_rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
root.title("Hello Python")
root.configure(bg="#010523")
root.iconbitmap('logo.ico')
root.geometry("400x500")
frame_main = tk.Frame(root, bg="#010523")
frame_main.grid(sticky='news')
# ********************header frame********************************
header_frame = LabelFrame(frame_main, bg="#010523", border=0, height=100)
header_frame.grid(row=0, column=0, columnspan=2, sticky='ew')
width =50
height =50
photo= Image.open("logo.png")
photo= photo.resize((width, height),Image.ANTIALIAS)
# create an object of PhotoImage
photoImg = ImageTk.PhotoImage(photo)
photo_label= Label(header_frame, image=photoImg, bg="#010523")
photo_label.grid(row=0, column=0, rowspan=2)
# Label
public_broadcast = Label(header_frame, text="Public broadcast",
font="bold", bg="#010523", fg="white")
public_broadcast.grid(row=0, column=1)
_id = Label(header_frame, text="MY ID: 0013A20041EFD12C",
font="10", bg="#010523", fg="grey")
_id.grid(row=1, column=1, padx=10)
# ********************end of header frame*************************
# label1 = tk.Label(frame_main, text="Label 1", fg="green")
# label1.grid(row=0, column=0, pady=(5, 0), sticky='nw')
# label2 = tk.Label(frame_main, text="Label 2", fg="blue")
# label2.grid(row=1, column=0, pady=(5, 0), sticky='nw')
# label3 = tk.Label(frame_main, text="Label 3", fg="red")
# label3.grid(row=3, column=0, pady=5, sticky='nw')
# Create a frame for the canvas with non-zero row&column weights
frame_canvas = tk.Frame(frame_main)
frame_canvas.grid(row=2, column=0, pady=(5, 0), sticky='nw')
frame_canvas.grid_rowconfigure(0, weight=1)
frame_canvas.grid_columnconfigure(0, weight=1)
# Set grid_propagate to False to allow 5-by-5 buttons resizing later
frame_canvas.grid_propagate(False)
# Add a canvas in that frame
canvas = tk.Canvas(frame_canvas, bg="yellow")
canvas.grid(row=0, column=0, sticky="news")
# Link a scrollbar to the canvas
vsb = tk.Scrollbar(frame_canvas, orient=VERTICAL, command=canvas.yview)
vsb.grid(row=0, column=1, sticky='ns')
canvas.configure(yscrollcommand=vsb.set)
# Create a frame to contain the buttons
frame_buttons = tk.Frame(canvas, bg="blue")
# Add 9-by-5 buttons to the frame
last_frame_row = 3
frame_canvas.config(width=400, height=300)
# Entering self msg frame with text
def add_msg_frame():
global last_frame_row
msg = "This is a test msg"
# msg = e.get()
# e.delete(0, END)
new_frame = Frame(frame_buttons, bg="#4857a8", borderwidth=0)
new_frame.grid(row=last_frame_row, column=1, columnspan=2, sticky='e', pady=5)
last_frame_row = 1
new_label = Label(new_frame, text=msg, font="10", bg="#4857a8", fg="white")
new_label.grid(row=0, column=0)
canvas.create_window((0, 0), window=frame_buttons, anchor='nw')
def add_reply_msg(device_id="0983ADFCD9827sd", msg="this is a sample message"):
global last_frame_row
new_frame = Frame(frame_buttons, bg="#1f243f", borderwidth=0)
new_frame.grid(row=last_frame_row, column=0, columnspan=2, sticky='w', pady=5)
last_frame_row = 1
new_label = Label(new_frame, text=device_id, bg="#1f243f", font="10", fg="#a6a6a6")
new_label.grid(row=0, column=0)
new_label2 = Label(new_frame, text=msg, font="10", bg="#1f243f", fg="white")
new_label2.grid(row=1, column=0)
# Update buttons frames idle tasks to let tkinter calculate buttons sizes
# for i in range(30):
# add_msg_frame()
add_reply_msg()
add_reply_msg()
add_msg_frame()
frame_buttons.update_idletasks()
# Set the canvas scrolling region
canvas.config(scrollregion=canvas.bbox("all"), yscrollcommand=vsb.set)
canvas.create_window((0, 0), window=frame_buttons, anchor='nw')
canvas.bind('<Configure>', lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
# # Entry
eFrame = Frame(root, width=400, height=100)
eFrame.grid(row=1000, column=0)
e = Entry(eFrame, width=50)
e.grid(row=0, column=0)
ebtn = Button(eFrame, text="Send", bg="skyblue", command=add_msg_frame)
ebtn.grid(row=0, column=1)
# Launch the GUI
root.mainloop()
Please give me suggestions that how can i enable scrollbar when add a frame by clicking the send button.
Thank you.
CodePudding user response:
You need to update the scrollregion
whenever you add or modify things on the canvas.
CodePudding user response:
frame_buttons
will be resized when items are added to it, so you need to update the scrollregion
of the canvas in this case via bind('<Configure>', ...)
. Also it is better to call canvas.create_window((0, 0), window=frame_buttons, anchor='nw')
once outside the function add_msg_frame()
:
...
# Create a frame to contain the buttons
frame_buttons = tk.Frame(canvas, bg="blue")
# call canvas.create_window(...) once here
canvas.create_window((0, 0), window=frame_buttons, anchor='nw')
# update scrollregion of canvas whenever the frame is resized
frame_buttons.bind('<Configure>', lambda e: canvas.config(scrollregion=canvas.bbox('all')))
...