Ruben van der Heijden
Ruben van der Heijden

Reputation: 55

how to allow Tkinter to generate a listbox from list input

I am trying to insert the output of a SparQL query (via rdflib) into a listbox in a Tkinter GUI. The current version of the code is:

Button_4 = Button(self, text="Load object list", command=self.populateListbox)
Button_4.grid(row=14, column=0, sticky=N)

self.List_3 = Listbox(self, height=7, width=40, selectmode='single', exportselection=0)
self.List_3.grid(row=15, column=0, sticky=N)

  def populateListbox(self):

    g=rdflib.Graph()
    filename = r'bim\Perceel4.owl'
    g.load(filename, format='xml')
    Layer = u'Asfaltplak_onderlaag'

    qres = g.query(
    """SELECT DISTINCT ?value ?name ?file ?frag
       WHERE {
             -- SparQL query for results--
                }""",
     initNs=dict(
        cbim=Namespace("http://www.coinsweb.nl/cbim-1.1.owl#")))

    for row in qres:
       if (rdflib.term.Literal(Layer, datatype=rdflib.term.URIRef(u'http://www.w3.org/2001/XMLSchema#string')) in row):

        self.lst  = row['file']

    self.List_3.insert("end",self.lst)

If I print the SparQL query using the command: print: self.lst, I get the following print message:

DTB HRB 166.495 - 166.038 VH_gml.xml
DTB OPR 167.647 - 167.601 VH_gml.xml
DTB PST 170.824 - 170.769 VH_gml.xml
DTB HRB 166.038 - 164.169 VH_gml.xml
DTB PST 167.696 - 167.767 VH_gml.xml
...etc (more of these filenames)

When I run the program and click on the button to populate the listbox, I only get one name in the listbox, namely the first one of the list. How can I get the entire list inserted in the listbox, such as it comes out the print command?

Ps. I tried the '*' by using self.List_3.insert("end",self.*lst), but that only splits the name into a list that consist of the name split, as such:

D
T
S
1
2
..etc

U p d a t e :

I have added the list split as such:

...
        output  = row['file']
        self.lst = output.split("\n")

    self.List_3.insert("end",*self.lst)

but it still only gives one list entry in the listbox (the last one of the list). If I print self.lst in the new setup, it prints:

[u'DTB HRB 167.639 - 167.696 VH_gml.xml']
[u'DTB PST 167.134 - 167.274 VH_gml.xml']
[u'DTB HRB 166.038 - 164.169 VH_gml.xml']

...etc

Upvotes: 3

Views: 6201

Answers (1)

Lafexlos
Lafexlos

Reputation: 7735

import Tkinter as tk

def populateListbox(lstt):
    listbox.insert("end", *lstt)

root = tk.Tk()
listbox = tk.Listbox(root)
listbox.pack()
lst = ["one", "two", "three", "four"]
btn = tk.Button(root, text="Populate listbox", command = lambda: populateListbox(lst))
btn.pack()

root.mainloop()

This is the simplified version of how you can populate listbox with a list of items. If you are getting list in your callback, you can remove lambda and parameter which leads to something like this.

def populateListbox():
    lst = [...] #gathered inside
    listbox.insert("end", *lst)

btn = tk.Button(..., command = populateListbox)

Also, those return statement in selectOwl is useless since there is nothing to assign that return values. Try to use your value in your command if they are needed.

Looking at the edit, it seems like all items in a single string. You need to split them by something. (In here it seems like it is new line \n). .split() will create a list then you can use *lst format.

outp = "DTB HRB 166.495 - 166.038 VH_gml.xml\nDTB OPR 167.647 - 167.601 VH_gml.xml\nDTB PST 170.824 - 170.769 VH_gml.xml"

print outp
DTB HRB 166.495 - 166.038 VH_gml.xml
DTB OPR 167.647 - 167.601 VH_gml.xml
DTB PST 170.824 - 170.769 VH_gml.xml

lst = outp.split("\n")

lst
Out[5]: 
['DTB HRB 166.495 - 166.038 VH_gml.xml',
 'DTB OPR 167.647 - 167.601 VH_gml.xml',
 'DTB PST 170.824 - 170.769 VH_gml.xml']

Upvotes: 4

Related Questions