I have two scripts:
Processor_child.py: Its purpose is to perform a number of data analysis and cleaning operations. This must perform the same operations when run alone (without Tkinter_parent.py) as it does when packaged into a GUI with Tkinter_parent.py.
Tkinter_parent.py: Its purpose is to provide a GUI for those who can't use Processor_child directly.
Where I'm struggling is to reproduce the python input
function from Processor_child.py in the instance where these two are used together as a GUI. I need to present a prompt to the user (done in code below), transfer that response to the GUI (various options available for this, such as Pipe), and only after that response has been passed have Processor_child resume its operation / retrieve the entry value (how?).
Example code of the issue, with ### comments ### indicating where code needs to be inserted to perform desired functionality:
### Processor_child.py ###
import pandas as pd
def smart_print(message, a_pipe = None):
if __name__ == "__main__":
print(message)
else:
a_pipe.send(message)
def review_with_user(var_names, dataset, a_pipe = None):
affirmed = []
review_message = 'Yes or no?'
if __name__ == "__main__":
review_response = input(review_message)
else:
smart_print(review_message, a_pipe)
review_response = 'Yes' ### INSTEAD SOMEHOW GET RESPONSE FROM Tkinter_parent.py ###
if review_response in ['Yes', 'yes']:
for v in set(var_names):
smart_print(dataset[v].dropna()[:8], a_pipe)
if __name__ == "__main__":
local_response = input(review_message)
else:
local_response = None ### INSTEAD SOMEHOW GET RESPONSE FROM Tkinter_parent.py ###
if local_response in ['Yes', 'yes']:
affirmed.append(v)
if __name__ == "__main__":
var_names = ['var1', 'var2']
df = pd.read_csv('dummy.csv')
review_with_user(var_names, df)
And Tkinter_parent.py:
### Tkinter_parent.py ###
from tkinter import *
from tkinter.filedialog import askopenfilename
from tkinter import ttk
from multiprocessing import Process, Pipe
import pandas as pd
import Processor_child
class GUI:
def __init__(self, master):
self.master = master
def gui_input(message):
def input_done(event=None):
### INSTEAD SOMEHOW send entry.get() back to Processor_child.py ###
pass
entry = Entry(frame)
input_label = ttk.Label(frame, text=message)
entry.bind("<Return>", input_done)
submit_button = ttk.Button(frame, text="Submit", command=input_done)
input_label.pack()
entry.pack()
submit_button.pack()
def file_select():
dataset_path = askopenfilename()
if __name__ == '__main__':
pipe1, pipe2 = Pipe()
some_vars = ['a var', 'another var']
a_df = pd.read_csv(dataset_path)
p_review = Process(target=Processor_child.review_with_user, args=(some_vars, a_df, pipe2))
p_review.start()
gui_input(pipe1.recv())
if __name__ == '__main__':
root = Tk()
my_gui = GUI(root)
root.style = ttk.Style()
root.style.configure('my.TButton')
root.style.configure('my.TLabel')
canvas = Canvas(root)
frame = Frame(canvas)
frame.place()
canvas.pack(side="left", fill="both", expand=True)
canvas.create_window((45,50), window=frame, anchor="nw")
ttk.Button(frame, text="Select", command=file_select).pack()
root.mainloop()
I've reviewed a number of related questions on SO, such as Getting a TKinter input stored into a string variable in the next function?: But they do not apply to cases where the input is being waited on before other actions are being performed (as in both cases I've presented here).
Other SO questions like How do I make the program wait for an input using an Entry box in Python GUI? don't work in these instances where the input in embedded within a loop within an executing function in another script; they rely on the 'waiting' being done within the GUI script itself.