Skip to content Skip to sidebar Skip to footer

How Can I Implement An `input` Method In A Tkinter Parent Script, With The Displayed Prompt And Return Value Being Sent Back To A Child Script?

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 T

Solution 1:

Note: This only works in rare cases. It is not a true 'solution'... I still face this issue. Fixing the approach below has its own SO question: Tkinter application 'freezes' while continually polling Pipe for contents (multiprocessing)


I've been able to find a pseudo-solution in which I add while loops that poll the Pipe, and upon finding that the Pipe does contain content, request the data in the Pipe. These while loops easily overload the application, and only seem to work in a simplified case. Definitely not the best way.

See amended code:

### processor_child.py ###import pandas as pd
from multiprocessing import *
import time

defsmart_print(message, a_pipe = None):
    if __name__ == "__main__":
        print(message)
    else:
        a_pipe.send(message)

defreview_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)
        while a_pipe.poll() != True:
            time.sleep(0.1)

        review_response = a_pipe.recv()

    if review_response in ['Yes', 'yes']:
        for v in dataset.columns:
            smart_print(dataset[v].dropna(), a_pipe)
            if __name__ == "__main__":
                local_response = input(review_message)
            else:
                while a_pipe.poll() != True:
                    time.sleep(0.1)
                local_response = a_pipe.recv()
            if local_response in ['Yes', 'yes']:
                affirmed.append(v)

        smart_print(affirmed, a_pipe)

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
import time

class GUI:
    def __init__(self, master):
        self.master = master

def gui_input(message, a_pipe = None):
    def input_done(event=None):
        entry.pack_forget()
        input_label.pack_forget()
        submit_button.pack_forget()
        a_pipe.send(entry.get())
        next_one(a_pipe)

    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(), pipe1)

        #time.sleep(1)
def next_one(pipe1):
    while pipe1.poll() != True:
        time.sleep(0.1)

    gui_input(pipe1.recv(), pipe1)

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()

Post a Comment for "How Can I Implement An `input` Method In A Tkinter Parent Script, With The Displayed Prompt And Return Value Being Sent Back To A Child Script?"