1

I have the folling tkinter UI that I am building that on load does not immediately load the listbox data, and I'm not sure why. Instead, on load I get the scrollbar and an empty listbox (the button shows up fine too). As soon as I interact with the window at all, the contents of the listbox show up:

from tkinter import *

gui = Tk()
gui.eval('tk::PlaceWindow . center')
# gui.geometry("500x200")

top_frame = Frame(gui)
top_frame.pack(side=TOP)

bot_frame = Frame(gui)
bot_frame.pack(side=BOTTOM)

scrollbar = Scrollbar(top_frame)
scrollbar.pack(side=LEFT, fill=Y)

lb = Listbox(top_frame)
lb.pack()

def onselect(evt):
    w = evt.widget
    index = int(w.curselection()[0])
    value = w.get(index)
    print(index, value)

lb.bind('<<ListboxSelect>>', onselect)

lb.insert(0, *range(100))

scrollbar.config(command=lb.yview)
lb.config(yscrollcommand=scrollbar.set)

quit_button = Button(bot_frame, text="Quit", command=gui.destroy)
quit_button.pack()

mainloop()

It seems like there is some ordering in which the pack calls need to occur that I can't seem to get right.

How can I get the items to show up on window load while keeping the scrollbar on the left?

EDIT 1: system info:

platform.platform(): macOS-12.6.2-x86_64-i386-64bit
platform.python_version(): 3.10.6
tk.TkVersion: 8.6
javamonkey79
  • 17,443
  • 36
  • 114
  • 172
  • 2
    The order you pack things is indeed very important. For the canonical description of how the packer works, see [The packer algorithm](https://tcl.tk/man/tcl8.6.13/TkCmd/pack.htm#M27) in the official tk documentation. It will tell you everything you need to know about how `pack` works. [This answer](https://stackoverflow.com/questions/57390278/tkinter-pack-method-confusion/57396569#57396569) gives an illustrated guide to how the packer works for one specific type of layout problem. – Bryan Oakley Feb 24 '23 at 01:42
  • 1
    When I run your code, the listbox is immediately filled with all of the numbers. Are you running on OSX with the system-supplied version of tkinter? – Bryan Oakley Feb 24 '23 at 01:43
  • @BryanOakley yes, I am running on OSX! I am not sure if it is the system-supplied version, or not. – javamonkey79 Feb 24 '23 at 04:32
  • 1
    I'm also not able to reproduce your issue on Windows 11, with python 3.11.0 and tkinter 8.6.12. What python version are you running and what [patchlevel](https://stackoverflow.com/a/62761906/13629335) of tkinter are you running ? In fear of stating the obvious, it seems a rendering problem, it might be solvable with `widget.update_idletasks()` after `lb.insert..` – Thingamabobs Feb 24 '23 at 10:59
  • 1
    pycharm, pytorch, etc? – toyota Supra Feb 24 '23 at 12:06
  • @Thingamabobs `widget.update_idletasks()` did the trick. I have no idea _why_ but it works :shrug: – javamonkey79 Feb 24 '23 at 22:28
  • @toyotaSupra I am not using pycharm or pytorch – javamonkey79 Feb 24 '23 at 22:32
  • @javamonkey79, sometimes especially at initiation of the application there is a flood of things tkinter does in the background and pending calls get in the waiting queue/waiting for the mainloop. I've read that many TCL'er are waiting for the application to be mapped and after that forcing it to redraw is a widespread technique to make sure things get considered. – Thingamabobs Feb 25 '23 at 06:36

1 Answers1

0

sometimes especially at initiation of the application there is a flood of things tkinter does in the background and pending calls get in the waiting queue/waiting for the mainloop. I've read that many TCL'er are waiting for the application to be mapped and after that forcing it to redraw is a widespread technique to make sure things get considered.

widget.update_idletasks() should do that for you.

Thingamabobs
  • 7,274
  • 5
  • 21
  • 54