Search code examples
pythonlistcsvtkinteroptionmenu

python tkinter import csv data to OptionMenu


I want to fill some OptionMenu's with data I have previously scraped from a url.

Ex:

    with open('clubs.csv', newline ='') as club:
    reader=csv.reader(club)
    dummy_club = []
    dummy_club.extend(reader)

Later I want to use this in one of my OptionMenus

Ex:

sv_club = StringVar()    
d_club = OptionMenu(app,variable=sv_club,value=dummy_club)

Unfortunately the list of around 700 items is put all in one row/line like when I click on my d_club OptionMenu on this screenshot: enter image description here

Any Idea how I need to chance the code that after each item there will be a new row?

When I directly import my scraped data as a list into my OptionMenu it looks perfect. But when I try to import the in .csv saved data when I start my GUI (so when I call app.mainloop()) it is messed up.

EDIT:

added code I use with my scraper, to get the .csv file:

def scrape():
    li_clubs = []
    print('getting clubs...\n')
    #click the dropdown menue to open the folder
    club_dropdown_menu = driver.find_element_by_xpath('/html/body/main/section/section/div[2]/div/div[2]/div/div[1]/div[1]/div[8]/div')
    club_dropdown_menu.click()
    time.sleep(1)

    # scrape all text
    scrape_clubs = driver.find_elements_by_xpath("//li[@class='with-icon' and contains(text(), '')]")
    for club in scrape_clubs:
        export_clubs = club.text
        export_clubs = str(export_clubs)
        export_clubs = export_clubs.replace(',', '')
        li_clubs.append(export_clubs)
        
    m_club = d_club.children['menu']
    for val in li_clubs:
        m_club.add_command(label=val,command=lambda v=sv_club,l=val:v.set(l))

    with open('clubs.csv', 'w', newline='') as club:
        writer = csv.writer(club, quotechar=None)
        for i in li_clubs:
            writer.writerow(i.split(','))

The code is build like that, so that I can update the OptionMenu's if I need to. The funcion def scrape(): is bound to a button. So that when I press the utton, I do a scrape and update my optionMenu.

After that I write the list li_clubs into a clubs.csvfile.

Because the data I need doesn't change very often, I have bound the scrape to a button so I can push it if I need.

But I want to load the data from the .csv file into my OptionMenu after each start. So that I can use the scraped data directly.


Solution

  • You need to use the expansion/unpack/splat operator *. However, since the data is a list of lists (or tuple of tuples) you need to convert the inner lists to strings before doing so since the option menu requires a list of strings.

    It might look something like this:

    dummy_club = [" ".join(row) for row in dummy_club]
    d_club = OptionMenu(app, sv_club, *dummy_club)
    

    Though, an OptionMenu with 700 values will be very difficult to use. You should probably consider a ttk Combobox widget.