'pysimplegui auto-fill depending on listbox selection / text replacement in file - Python

Example yaml file being edited:

FTP_Folder: C:/Users/admin/Documents/Data

DBtables:
  CurrentMinuteLoad:
    CSV_File: trend.csv
    Table_Name: currentminuteload
  aaa:
    CSV_File:aaa
    Table_Name:aaa

working with listbox and keys, I have the following window:

GUI Image

with the following code,

def make_edit():
    layout = [[sg.Text("Reference Name")],
              [sg.Listbox(config["DBtables"], size=(20,4), key='LIST', enable_events=True)],
              [sg.Text(" ")],
              [sg.Text("Reference Name:"), sg.Input(), sg.Button('Edit Ref')],
              [sg.Text("CSV File:"), sg.Input(), sg.Button('Edit CSV')],
              [sg.Text("DB Table Name:"), sg.Input(), sg.Button('Edit Tbl')],
              [sg.Text(" ")],
              [sg.Button('Delete'), sg.Button('Back')]]

    return sg.Window("Edit or Delete Existing Table", layout, finalize=True)

First Question: I am trying to get the three input boxes to auto-fill based on the choice made from the listbox. Tried sg.Input(values['KEY']) for the first box, but that didn't work.

Second Question tied to the first,

def edit_ref():
    ref_name = sg.PopupGetText('New Reference Name')
    if ref_name != None:
        sg.Popup('Table reference name has successfully changed to the following,', ref_name)

def edit_csv():
    csv_name = sg.PopupGetText('New CSV File Name')
    if csv_name != None:
        sg.Popup('CSV file name has successfully changed to the following,', csv_name)

def edit_tbl():
    tbl_name = sg.PopupGetText('New DB Table Name')
    if tbl_name != None:
        sg.Popup('DB table name has successfully changed to the following,', tbl_name)

The best way to edit each of the lines?

I have a similar def that edits the FTP_Folder in the yaml file using the following code,

if folder != None:
    with open("config.yml", "r+") as f:
        contents = f.read()
        f.seek(0)
        f.write(contents.replace(config["FTP_Folder"], folder))
        f.truncate()
        f.close()
    sg.popup ('Folder Updated')

I could likely get it to work using similar coding, but the problem with that is that it only lets me edit the file once per GUI session, which is something I'm also trying to work out.



Solution 1:[1]

1st question's answer

[sg.Listbox(list(config["DBtables"]), key='LIST', enable_events=True)],

Create the Listbox like the one above making sure that it is Listbox(list('what you want to list)..

Then you can call that value by using items = values["LIST"][0]

2nd question's answer

I ended up modifying it so that the reference name and table name were the same. Didn't see a reason for them not to be. The code for instant modifications to the yaml file ended up being the following,

def edit_tbl():
    tbl_name = sg.PopupGetText('New Table Name',default_text=items)
    with open("config.yml", "r+") as f:
        data = yaml.safe_load(f)
    if tbl_name != None:
        if tbl_name != "":
            dbtables = data['DBtables']
            if tbl_name in dbtables:
                sg.popup ('Table "' + tbl_name +'" already exists')
                return items
            data["DBtables"][items]["Table_Name"] = tbl_name
            data["DBtables"][tbl_name] = data["DBtables"][items]
            del data['DBtables'][items]
            with open('config.yml', 'w') as file:
                yaml.safe_dump(data, file)
            sg.Popup('Table name has successfully changed to the following,', tbl_name)
            return tbl_name
        else:
            sg.popup ('The Table Name was not updated because the field was left blank')
            return items
    return items
        

def edit_csv():
    with open("config.yml", "r+") as configFile:
        config = yaml.safe_load(configFile)
    csv_name = sg.PopupGetText('New CSV File Name',default_text=config["DBtables"][items]["CSV_File"])
    if csv_name != None:
        if csv_name != "":
            config["DBtables"][items]["CSV_File"] = csv_name
            with open('config.yml', 'w') as file:
                yaml.safe_dump(config, file)
            sg.Popup('CSV file name has successfully changed to the following,', csv_name)
            return
        else:
            sg.popup ('The CSV File was not updated because the field was left blank')

Extra Fluff

I reworked the edit FTP file to the following,

def edit_folder():
    with open("config.yml", "r+") as configFile:
        config = yaml.safe_load(configFile)
    folder = sg.popup_get_folder('Please select folder')
    if folder != None:
        if folder != "":
            config["FTP_Folder"] = folder
            with open('config.yml', 'w') as file:
                yaml.safe_dump(config, file)
            sg.popup ('Folder Updated')
        else:
            sg.popup ('The folder was not updated because the field was left blank')

And just to complete the yaml modifications for anyone interested, the "add new table" code snippet was this,

def add_table():
    with open("config.yml", "r+") as file:
        data = yaml.safe_load(file)
    dbtables = data['DBtables']

    if values['Table_Name'] != "" and values['CSV_File'] != "":
        #check if DBtable exists
        if values['Table_Name'] in dbtables:
            sg.popup ('Table "' + values["Table_Name"] +'" already exists')
            return

       #write new table to config.yml     
        dbtables[values['Table_Name']] = d = {}
        for x in ['CSV_File', 'Table_Name']:
            d[x] = values[x]
        with open('config.yml', 'w') as file:
            yaml.safe_dump(data, file)
        sg.popup('The table "' + values['Table_Name'] + '" will be added to PG Admin during the next scheduled upload')
    else:
        sg.popup ('Ensure there are values in both fields')

It may not be the best way to do it, but it gets the job done. Hopefully this helps someone else.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1