Chinmay Datar
Chinmay Datar

Reputation: 97

Interactive popup window in pysimplegui

I have created a UI for prediction which looks like this

enter image description here

The code for this is:

items = [
    "Automobile", "Chemical", "Engineering/Consulting", "FMCG",
    "Healthcare/Hospitality", "Infrastructue", "IT/Comm/DC", "Manufacturing",
    "Mines", "Energy/Oil & Gas", "Pharma", "Retail", "Cement",
]
length = len(items)
size = (max(map(len, items)), 1)

sg.theme("DarkBlue3")
sg.set_options(font=("Courier New", 11))

column_layout = []
line = []
num = 4
for i, item in enumerate(items):
    line.append(sg.Button(item, size=size, metadata=False))
    if i%num == num-1 or i==length-1:
        column_layout.append(line)
        line = []

layout = [
    [sg.Text('Choose the Industry')],
    [sg.Column(column_layout)],
    [sg.Text(size=(50,1),key=('loaded'))],
    [sg.Text('Enter Observation/Recommendation: ', size =(26, 1)), sg.InputText(do_not_clear=False)],
    [sg.Button("Predict Risk", bind_return_key=True,metadata=False)],
    [sg.Text(size=(30,1),key=('output'))],
    [sg.Text('If the above prediction is correct select \'yes\' else select the correct risk.')],
    [sg.Button("Yes"),sg.Button("Low"),sg.Button("Medium")],
    [sg.Text(size=(30,2),key=('trained'))],
    [sg.Button("Exit"),sg.Button("Clear Fields")]
]

window=sg.Window("Risk Predictor", layout, use_default_focus=False, finalize=True)
for key in window.key_dict:    # Remove dash box of all Buttons
    element = window[key]
    if isinstance(element, sg.Button):
        element.block_focus()

#window=sg.Window("Risk Predictor",layout)

while True:
    event, values = window.read()
    # End program if user closes window or
    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    if event == "Mines":
        window['Mines'].metadata = True
        
        df=pd.read_csv('./Audit data_Observation & Risk.csv')
        #df1=balancing(df)
        df1=df
        window['loaded'].update("Mines data is loaded.")
        obs=values[0]
        #if obs!="":
    if event == "Predict Risk" and window["Mines"].metadata and values[0]!="":
        with open("./sgd.pickle", 'rb') as f:
            sgd = pickle.load(f)
        window['trained'].update("")
        output=output_sample(df1,sgd,values[0])
        output1="The Risk prediction is "+output
        window['output'].update(output1)
        window['Predict Risk'].metadata=True
    if event == 'Yes' and window['Predict Risk'].metadata==True:
        newy=preprocess_text(output)
        retrain(df1,values[0],newy)
        window['trained'].update("The model has been trained on new data.")
        continue
    elif event =='Low' and window['Predict Risk'].metadata==True:
        newy="Low"
        retrain(df1,values[0],newy)
        window['trained'].update("The model has been trained on updated data.")
        continue
    elif event =='Medium' and window['Predict Risk'].metadata==True:
        newy="Medium"
        retrain(df1,values[0],newy)
        window['trained'].update("The model has been trained on updated data.")
        continue
    if event=='Clear Fields':
        window['loaded'].update("")
        window['output'].update("")
        window['trained'].update("")
        values[0]=''
        window[event].metadata=False
        window['Predict Risk'].metadata=False
window.close()

Its not yet complete by any means. I want to divide this UI into three parts.

  1. When the application is run only Choose the industry part comes.
  2. When Industry is selected a popup opens to Enter the Observation and Predict Risk.
  3. When Predict Risk is clicked another pop up showing the prediction and showing the feedback mechanism.

So my question is how do I make interactive popups?

Upvotes: 2

Views: 7034

Answers (1)

Jason Yang
Jason Yang

Reputation: 13061

Just create a new window with modal=True in your function with arguments passed and return what value your need. Option modal=True if True then this window will be the only window a user can interact with until it is closed.

The settings modal=True for previous window will be removed, so it's better only for two windows existing at the same time. Of course, more windows also work, but need more settings for it.

Demo code here,

import PySimpleGUI as sg

def block_focus(window):
    for key in window.key_dict:    # Remove dash box of all Buttons
        element = window[key]
        if isinstance(element, sg.Button):
            element.block_focus()

def popup_predict_risk(industry):

    col_layout = [[sg.Button("Predict Risk", bind_return_key=True), sg.Button('Cancel')]]
    layout = [
        [sg.Text(f"Industry: {industry}")],
        [sg.Text('Enter Observation/Recommendation: '), sg.InputText(key='Observation')],
        [sg.Column(col_layout, expand_x=True, element_justification='right')],
    ]
    window = sg.Window("Predict Risk", layout, use_default_focus=False, finalize=True, modal=True)
    block_focus(window)
    event, values = window.read()
    window.close()
    return values['Observation'] if event == 'Predict Risk' else None

def popup_prediction(industry, observation):

    col_layout = [[sg.Button('OK')]]
    layout = [
        [sg.Text("Here's the result\n")],
        [sg.Text(f"industry   : {industry}")],
        [sg.Text(f"Observation: {observation}")],
        [sg.Column(col_layout, expand_x=True, element_justification='right')],
    ]
    window = sg.Window("Prediction", layout, use_default_focus=False, finalize=True, modal=True)
    block_focus(window)
    event, values = window.read()
    window.close()
    return None

items = [
    "Automobile", "Chemical", "Engineering/Consulting", "FMCG",
    "Healthcare/Hospitality", "Infrastructue", "IT/Comm/DC", "Manufacturing",
    "Mines", "Energy/Oil & Gas", "Pharma", "Retail", "Cement",
]
length = len(items)
size = (max(map(len, items)), 1)

sg.theme("DarkBlue3")
sg.set_options(font=("Courier New", 11))

column_layout = []
line = []
num = 4
for i, item in enumerate(items):
    line.append(sg.Button(item, size=size, metadata=False))
    if i%num == num-1 or i==length-1:
        column_layout.append(line)
        line = []

layout = [
    [sg.Text('Choose the Industry')],
    [sg.Column(column_layout)],
]
window=sg.Window("Risk Predictor", layout, use_default_focus=False, finalize=True)
block_focus(window)

sg.theme("DarkGreen3")
while True:

    event, values = window.read()
    if event == sg.WINDOW_CLOSED:
        break
    elif event in items:
        industry = event
        observation = popup_predict_risk(industry)
        if observation is not None:
            popup_prediction(industry, observation)

window.close()

Upvotes: 4

Related Questions