Python, tkinter and the scrollbar in a grid - python-3.x

This is me trying to get a ListBox with a Scrollbar. I've read about 20 other answers on this site and none seem to work in my situation, so I have to ask my own.
I have a LabelFrame widget in which I have a few labels and a ListBox widget. I want the ListBox widget to have a scrollbar. I cannot seem to get it to work.
Here is the offending code:
self.lbDates = tk.Listbox(master=group, width=12)
self.lbDates.grid(row=3, column=1, padx=3, pady=3)
self.scrollDates = tk.Scrollbar(self.lbDates, orient="vertical")
self.scrollDates.config(command=self.lbDates.yview)
self.scrollDates.grid(row=3, column=1)
self.lbDates.config(yscrollcommand=self.scrollDates.set)
A few questions: is the scrollbar supposed to be in the same space (i.e. the same grid row and column) as the ListBox widget? I supposed it should be, but given how much trouble I've had with this, I feel I should ask.
I should say that the list box is populated by pressing a button elsewhere. Without the scrollbar in place, this date is populated correctly so I'm assuming the problem isn't there.
What happens when I run this code? Well I don't see a ListBox, but I to see the scroll bar. Now when there's supposed to be data in there (and I know because I populate it), I see what you might imagine is the correct scrollbar, although the ListBox is either invisible or hidden or something. It flickers on for a fraction of a second when it's populated but then is hidden again.
I can show you, in fact, an example of this.
The top one has no data in and the second has data in. Of course you can't see the data, but you can see that it's supposed to be there. And if I remove the scrollbar, I do get the data I expect in the ListBox widgets. I would like to show an image of the moment it populates before it disappears but it seems like a single frame and I can't catch it.
I'm sure my mistake must be something very simple here, and I very much hope someone can assist. I am using tkinter for the widgets and Python 3.7.
Edit: I have made some alterations as suggested below, so that my ListBox and Scrollbar now exist in a Frame and that Frame is within the LabelFrame object. As follows:
fr = tk.Frame(master = group)
fr.grid(row=4, column=1)
self.lbDates = tk.Listbox(master=fr, width=12)
self.lbDates.pack()
self.scrollDates = tk.Scrollbar(master=self.lbDates, orient="vertical")
self.scrollDates.config(command=self.lbDates.yview)
self.scrollDates.pack()
self.lbDates.config(yscrollcommand=self.scrollDates.set)
Unfortunately there is no difference and I seem to be experiencing the exact same problems as before.

is the scrollbar supposed to be in the same space (i.e. the same grid row and column) as the ListBox widget?
It's up to you. Typically you do not put the scrollbar inside the listbox, as it would obscure some of the data in the listbox. The listbox and scrollbar will have the same parent. If you're using grid, usually the vertical scrollbar belongs in the column immediately to the right of the listbox.
What happens when I run this code? Well I don't see a ListBox, but I to see the scroll bar.
That is because the listbox shrinks to fit its children. The listbox is there, but it's only as wide and tall as the scrollbar. This is another reason why you shouldn't put the scrollbar inside the listbox.
If you want the scrollbar to appear as if it's inside the listbox, the best practice is to create a frame that holds the listbox and scrollbar.
You can make the frame sunken and the listbox flat, and it will give the illusion that the scrollbar is inside the listbox. You can then put that frame anywhere you like in your UI and the scrollbar will always be with the listbox.
Both the listbox and the scrollbar need to be children of the frame for this to work.
Here's a simple example:
import tkinter as tk
root = tk.Tk()
lb_frame = tk.Frame(root, bd=1, relief="sunken")
listbox = tk.Listbox(lb_frame, bd=0, yscrollcommand=lambda *args: vsb.set(*args))
vsb = tk.Scrollbar(lb_frame, orient="vertical", command=listbox.yview)
vsb.pack(side="right", fill="y")
listbox.pack(side="left", fill="both", expand=True)
lb_frame.pack(padx=20, pady=20)
for i in range(1, 100):
listbox.insert("end", f"Item {i}")
root.mainloop()

Related

Is there a way of adding a scrollbar horizontally and vertically to a Text Input in Kivy?

I am new to Kivy and Pyhton and I want to put a scrollbar horizontally and vertically to a Text Input. I don’t want to use a ScrollView, because I am making a desktop app and it is not that intuitive as the user has to click and drag up and down or sidewards in the Text Input". I also found on the internet how to make a draggable scrollbar using a slider (https://github.com/kivy/kivy/wiki/A-draggable-scrollbar-using-a-slider), but I have’t been able to add it to the Text Input. Could anyone help me please?

Automatically scroll down Listbox in Tkinter app

Hi guys I'm making this chat app with tkinter and it works perfectly except by the fact that the text I post in my Listbox, don't shows up the way I want. Once the space in the Listbox finishes, I have to manually scroll down to see recent messages. My question is, what can I do to make the Listbox automatically scroll down when it gets fill. This is the part of the code of the Listbox
lista=Listbox(raiz,font=('Arial'))
lista.pack(side=LEFT,padx=10,pady=10,ipadx=200,fill=X,expand=True )
And this is where I posted:
def post(text,n=0):
winsound.Beep(400,150)
if n==0:
lista.insert(END,text)
campo.delete(0,1000)
else:
for i in text:
lista.insert(END,i)
If you can help me it will be great. Thanks!!!
You need add this line lista.see(tkinter.END) before lista.insert(END,text)
You should clear the Listbox widget before you display the current or insert
def post(text,n=0):
winsound.Beep(400,150)
if n==0:
lista.delete(0, END) # this to clear the listbox and display the current content in the listbox
lista.insert(END,text)
campo.delete(0,1000)
else:
for i in text:
lista.insert(END,i)
Or you can place the new content at top of Listbox like this,
def post(text,n=0):
winsound.Beep(400,150)
if n==0:
return
lista.insert(n-1, text)
campo.delete(0,1000)
else:
for i in text:
lista.insert(END,i)
Since you didn't post your full code or minimal am assuming this how it is.

VBA Vertical scrollbar thumb size

I have a form where controls are dynamically created, the scrollbar included, with
Set theScroll = UserForm1.Controls.Add("Forms.ScrollBar.1", "sc1", True)
but I'm having difficulty resizing or changing the scrollbar thumb size other than the min value, it doesn't seem to have an event or function for resize.
I've also tried using
Userform1.ScrollBars = fmScrollBarsVertical
but I can't move it anywhere around the form since I need to have the said scrollbar slightly off of center of the form.

Tkinter Combobox button size

So I need a BIG combobox, its for a touchscreen application. I've managed to get the drop-down list scaled up, the combobox taller, but the dropdown button is still the default width. How do I make it bigger?

Force Extjs grid to recalculate width - after hiding a simple "div" next to it

I have a grid in ExtJS and a div that I place or toggle to the left of it. This div is not managed by ExtJS.
When I show this div, the grid slips to the right and this div shows up on its left.
The problem I have is that when I hide the div, the grid squeezes and looses the full width it had based on the "fit" layout meaning there is some empty space left on the right of it now.
Now, as soon as I resize the window, it catches the event and resizes itself but not before it.
Anyone with any suggestions I could try in order to maintain the grid's stretch, your help is much appreciated.
Try explicitly calling doLayout() on the grid or the grid's parent, when the div is hidden.

Resources