Home > database >  Attaching scrollbar to listbox in tkinter window python
Attaching scrollbar to listbox in tkinter window python

Time:07-17

Need help in attaching the scrollbar to the listbox.I have tried several things & obviously I am not doing something correct. Any help/guidance will be really appreciated. I have attached a snapshot of how the tkinter window looks like.

from tkinter import *

app = Tk()

label1_text = StringVar()
part_label = Label(app, bg='#dfe3ee', text='Check1', font=('bold',12), pady=10, padx=20)
part_label.grid(row=0, column=0, sticky=W)
label1_entry = Entry(app, textvariable=label1_text)
label1_entry.grid(row=0, column=1)

label2_text = StringVar()
part_label = Label(app, bg='#dfe3ee', text='Check1', font=('bold', 12), pady=7, padx=20)
part_label.grid(row=1, column=0, sticky=W)
label2_entry = Entry(app, textvariable=label2_text)
label2_entry.grid(row=1, column=1)

label3_text = StringVar()
part_label = Label(app, bg='#dfe3ee', text='Check3', font=('bold', 12), pady=20)
part_label.grid(row=0, column=2)
label3_entry = Entry(app, textvariable=label3_text)
label3_entry.grid(row=0, column=3)

label4 = StringVar()
part_label = Label(app, bg='#dfe3ee', text='check4', font=('bold', 12), pady=7)
part_label.grid(row=1, column=2)
label4_entry = Entry(app, textvariable=label4)
label4_entry.grid(row=1, column=3)

B1_btn = Button(app, bg='#cd8de5', text='Button1',font=('bold', 11), width=12)
B1_btn.grid(row=3, column=1, padx=0, pady=5)

B2_btn = Button(app, bg='#cd8de5', text='Button2',font=('bold', 11), width=12 )
B2_btn.grid(row=4, column=1, padx=0, pady=5)

B3_btn = Button(app, bg='#d5a6e6', text='close',font=('bold', 11), width=12)
B3_btn.grid(row=50, column=2, sticky='E')

output_list = Listbox(app, height=20, width=100, border=5)
output_list.grid(row=20, column=0, columnspan=3, rowspan=6, pady=20, padx=20)

scrollbar = Scrollbar(app)
scrollbar.grid(row=20, column =3, rowspan=5, sticky=(N S))

output_list.configure(yscrollcommand=scrollbar.set)
scrollbar.configure(command=output_list.yview)

app.title('Test Tool')
app.geometry('900x900')
app.configure(bg='#dfe3ee')

app.mainloop()

CodePudding user response:

The listbox and the scrollbar works without any problem but your layout looks inconsistent. A good way to make layout with lots of widgets is, using the Frame to group the widgets and then place those widgets on the window.

It will look more professional and easy to manage once you group them up because now you will just have to deal with a frame inside your main app. Say you want to change the position of a label later, any change to it can mess up the entire layout of the app. But using frames, the change of position will be contained inside the frame only.

Look at how you can organize your widgets:

frame_app = Frame(app,background='#dfe3ee') # A frame for the top section. Also if you dont give background to the frame it will fill empty spaces with default background
frame_app.grid(row=0,column=0, sticky=W)

label1_text = StringVar()
# Set the parent to the frame instead of the app
part_label = Label(frame_app, bg='#dfe3ee', text='Check1', font=('bold',12), pady=10, padx=20)
part_label.grid(row=0, column=0, sticky=W)
label1_entry = Entry(frame_app, textvariable=label1_text)
label1_entry.grid(row=0, column=1)

label2_text = StringVar()
part_label = Label(frame_app, bg='#dfe3ee', text='Check1', font=('bold', 12), pady=7, padx=20)
part_label.grid(row=1, column=0, sticky=W)
label2_entry = Entry(frame_app, textvariable=label2_text)
label2_entry.grid(row=1, column=1)

label3_text = StringVar()
part_label = Label(frame_app, bg='#dfe3ee', text='Check3', font=('bold', 12), pady=20)
part_label.grid(row=0, column=2)
label3_entry = Entry(frame_app, textvariable=label3_text)
label3_entry.grid(row=0, column=3)

label4 = StringVar()
part_label = Label(frame_app, bg='#dfe3ee', text='check4', font=('bold', 12), pady=7)
part_label.grid(row=1, column=2)
label4_entry = Entry(frame_app, textvariable=label4)
label4_entry.grid(row=1, column=3)

B1_btn = Button(frame_app, bg='#cd8de5', text='Button1',font=('bold', 11), width=12)
B1_btn.grid(row=3, column=1, padx=0, pady=5)

B2_btn = Button(frame_app, bg='#cd8de5', text='Button2',font=('bold', 11), width=12 )
B2_btn.grid(row=4, column=1, padx=0, pady=5)

# Make a frame for the listbox and scrollbar
frame_listbox = Frame(app)
frame_listbox.grid(row=1,column=0)

output_list = Listbox(frame_listbox, height=20, width=100, border=5)
output_list.grid(row=0, column=0)

scrollbar = Scrollbar(frame_listbox)
scrollbar.grid(row=0, column=1, sticky=(N S)) # Also can say sticky='ns'
    
output_list.configure(yscrollcommand=scrollbar.set)
scrollbar.configure(command=output_list.yview)

# Outside the frame and in the main window because this button does not really fit the context of any frames
B3_btn = Button(app, bg='#d5a6e6', text='close',font=('bold', 11), width=12)
B3_btn.grid(row=2, column=0, sticky='E')

Here you are grouping the top section widgets to be inside a single frame and then you are using grid on that frame to place this on the first row. Then the listbox and scrollbar is placed onto another frame and then gridded onto the next row. This way you can see that you don't need row=20 or <column/row>span and just account for the needed rows and at the same time have a more organized layout.

To test out if the scrollbar works, you will have to insert enough items to fill the entire height of the listbox:

for i in range(50): # Dummy data
    output_list.insert(END, i)

Obviously you can also now manually add more padx and pady if you want to edit the space between widgets in the top section, those will be upto you.

CodePudding user response:

With the following small changes the scrollbar 'sticks' to the listbox:

scrollbar.grid(row=20, column =3, rowspan=6, sticky=(W N S)) puts the scrollbar to the left side of the grid.

output_list.grid(row=20, column=0, columnspan=3, rowspan=6) let the scrollbar 'stick' to the listbox.

enter image description here

The code below let you scroll the with items filled listbox with the scrollbar:

from tkinter import *

app = Tk()

label1_text = StringVar()
part_label = Label(app, bg='#dfe3ee', text='Check1', font=('bold',12), pady=10, padx=20)
part_label.grid(row=0, column=0, sticky=W)
label1_entry = Entry(app, textvariable=label1_text)
label1_entry.grid(row=0, column=1)

label2_text = StringVar()
part_label = Label(app, bg='#dfe3ee', text='Check1', font=('bold', 12), pady=7, padx=20)
part_label.grid(row=1, column=0, sticky=W)
label2_entry = Entry(app, textvariable=label2_text)
label2_entry.grid(row=1, column=1)

label3_text = StringVar()
part_label = Label(app, bg='#dfe3ee', text='Check3', font=('bold', 12), pady=20)
part_label.grid(row=0, column=2)
label3_entry = Entry(app, textvariable=label3_text)
label3_entry.grid(row=0, column=3)

label4 = StringVar()
part_label = Label(app, bg='#dfe3ee', text='check4', font=('bold', 12), pady=7)
part_label.grid(row=1, column=2)
label4_entry = Entry(app, textvariable=label4)
label4_entry.grid(row=1, column=3)

B1_btn = Button(app, bg='#cd8de5', text='Button1',font=('bold', 11), width=12)
B1_btn.grid(row=3, column=1, padx=0, pady=5)

B2_btn = Button(app, bg='#cd8de5', text='Button2',font=('bold', 11), width=12 )
B2_btn.grid(row=4, column=1, padx=0, pady=5)

B3_btn = Button(app, bg='#d5a6e6', text='close',font=('bold', 11), width=12)
B3_btn.grid(row=50, column=2, sticky='E')

output_list = Listbox(app, height=20, width=100, border=5)
output_list.grid(row=20, column=0, columnspan=3, rowspan=6) # was: , pady=20, padx=20)
for i in range(40): 
    output_list.insert(i, i 1)
scrollbar = Scrollbar(app)
scrollbar.grid(row=20, column =3, rowspan=6, sticky=(W N S)) # was: (N S)

output_list.configure(yscrollcommand=scrollbar.set)
scrollbar.configure(command=output_list.yview)

app.title('Test Tool')
app.geometry('900x900')
app.configure(bg='#dfe3ee')

app.mainloop()

Initially the scrollbar had not the right raw span and was placed in the center of the grid column. And the listbox paddding prevented 'sticking' the scrollbar to the listbox:

enter image description here

  • Related