1

I am trying to develop a script that allows me to keep my formatting within my listbox.

from Tkinter import *
from tabulate import tabulate
master = Tk()

listbox = Listbox(master)
listbox.pack()

table = [["spam",42],["eggs",451],["bacon",0]]
headers = ["item", "qty"]
tb = tabulate(table, headers, tablefmt="plain")

listbox.insert(END,tb)

mainloop()

End Result the listbox populated with the tb formatting:

enter image description here

QUESTION: HOW DO I GET MY LISTBOX TO APPEAR LIKE THE PICTURE ABOVE THAT I USED TABULATE TO FORMAT?

I've noticed treeview seems to have some limitations with the horizontal box and expanding the columns without adjusting the entire GUI so I'd decided this might be a more shake-shift way that will suit my needs just fine.

Josh Clayton
  • 97
  • 1
  • 9

1 Answers1

2

One option may be to use str.format() to align each insert into the listbox:

from Tkinter import *
import tkFont

master = Tk()
master.resizable(width=False, height=False)
master.geometry('{width}x{height}'.format(width=300, height=100))
my_font = tkFont.Font(family="Monaco", size=12) # use a fixed width font so columns align

listbox = Listbox(master, width=400, height=400, font=my_font)
listbox.pack()

table = [["spam", 42, "test", ""],["eggs", 451, "", "we"],["bacon", "True", "", ""]]
headers = ["item", "qty", "sd", "again"]

row_format ="{:<8}{sp}{:>8}{sp}{:<8}{sp}{:8}" # left or right align, with an arbitrary '8' column width 

listbox.insert(0, row_format.format(*headers, sp=" "*2))
for items in table:
    listbox.insert(END, row_format.format(*items, sp=" "*2))
mainloop()

Which appears to match the output you got using tabulate:

enter image description here
Another option could be use a Grid layout.

  • Brian - That's true, but will suffice. Thanks downshift! – Josh Clayton Feb 11 '17 at 15:01
  • @davedwards Thank you for this code, I'm trying to use it in a similar way however my list of lists under 'table' has all the variables grouped differently. I.E [["spam", "eggs", "bacon"],[42,451, "True"],["test", " ", " "],[" ", "we", " "]]. How can I change it to put the data in correctly? – OParker Jun 06 '18 at 09:51
  • @OParker I'm glad to hear the code was helpful for you. Your list contains lists of 3 items instead of 4 items, so we can change the `header` and `row_format` to length of 3, use `headers = ["item", "qty", "sd"]` and `row_format ="{:<8}{sp}{:>8}{sp}{:<8}"` – chickity china chinese chicken Jun 06 '18 at 17:05
  • @davedwards thank you for replying, sorry that was poor explaining on my part. The differences between our lists is that in your code you're taking n from each list. i.e "spam", "42", "test", " " and then appending under the header. Whereas with my data I would have all of the instances for "item" in the same list, then all of the instances of "qty" in the same list. Is there a different insert method? There would be 17 items per list with 8 headers. (I've changed the row format to reflect this). (I can open a question if you'd prefer) – OParker Jun 07 '18 at 07:57
  • Please can you give some explanation about sp=" "*2 and *headers (meaning of asterix?) – Jomme Dec 16 '22 at 18:51
  • @Jomme, good question! Each instance of the asterisk is a different use: In `*headers` the asterisk unpacks the items in the headers `item qty sd again` for more info on this, see [What does the star and doublestar operator mean in a function call?](https://stackoverflow.com/a/2921893/1248974), the other `sp=" "*2` is a multipler operation to repeat the space charater to separate the columns, `sp` variable is the placeholder in the string, so spacing the columns two spaces, for better explanation see [Repeat string to certain length](https://stackoverflow.com/a/3391106/1248974) – chickity china chinese chicken Dec 19 '22 at 03:56