[Python] Gui asks for input before asking a question

Discussão em 'Python' iniciado por Stack, Setembro 29, 2024.

  1. Stack

    Stack Membro Participativo

    I have a gui script that I use to call other script and call outputs from it. Only thing that happens is that the prints get rendered, but when it hits the input, it asks for the answer from user first before it prints the question from the input. But I want him to write the question first and then demand an answer.

    I think the problem is in the execute function, but I don't know what to do about it. My theory is that once the gui detects that it wants input from user, it switches to None and thus the condition in execute no longer applies and it can't render. But I don't know how to solve this. I am attaching below the script I am rendering:

    import time

    def choose_assignment():

    print("1. Mixing two liquids.")
    print("2. Dividing a larger volume into x beakers.")
    print("To select, enter a digit without a dot on the following line")
    assignment = int(input("Write the digit you choose:"))
    print("ahoj")
    print(f"You chose option {assignment}.")
    a = input("ahoj: ")
    print(a)
    if __name__ == "__main__":
    time.sleep(1) # Simulate some delay
    choose_assignment()


    and Gui script

    import tkinter as tk
    from tkinter.scrolledtext import ScrolledText
    import threading
    from subprocess import Popen, PIPE
    import time


    class Console(tk.Frame):
    """Simple console that can execute bash commands"""

    def __init__(self, master, *args, **kwargs):
    tk.Frame.__init__(self, master, *args, **kwargs)

    self.text_options = {
    "state": "disabled",
    "bg": "black",
    "fg": "#08c614",
    "insertbackground": "#08c614",
    "selectbackground": "#f01c1c"
    }

    self.text = ScrolledText(self, **self.text_options)
    self.text.pack(expand=True, fill="both")

    self.command = "" # Predefined command (script path)
    self.popen = None # Will hold a reference to a Popen object
    self.running = False # True if the process is running

    self.bottom = tk.Frame(self)

    # Input field for user input
    self.input_entry = tk.Entry(self.bottom, width=80)
    self.input_entry.pack(side="left", padx=5, pady=2)
    self.input_entry.bind("<Return>", self.send_input)

    # Button to start the script
    self.executer = tk.Button(self.bottom, text="Start Script", command=self.start_thread)
    self.executer.pack(side="left", padx=5, pady=2)

    # Button to clear the console output
    self.clearer = tk.Button(self.bottom, text="Clear", command=self.clear)
    self.clearer.pack(side="left", padx=5, pady=2)

    # Button to stop the running script
    self.stopper = tk.Button(self.bottom, text="Stop", command=self.stop)
    self.stopper.pack(side="left", padx=5, pady=2)

    self.bottom.pack(side="bottom", fill="both")

    def clear_text(self):
    """Clears the Text widget"""
    self.text.config(state="normal")
    self.text.delete(1.0, "end-1c")
    self.text.config(state="disabled")

    def clear(self, event=None):
    """Just clears the Text widget."""
    self.clear_text()

    def show(self, message):
    """Inserts message into the Text widget"""
    self.text.config(state="normal")
    self.text.insert("end", message + "\n")
    self.text.see("end")
    self.text.config(state="disabled")

    def start_thread(self, event=None):
    """Starts a new thread and calls process"""
    self.stop()
    self.running = True
    self.command = "C:/Python/python.exe C:/Python/afaina-evobliss-software-68090c0edb16/automatizace/script_run.py"
    threading.Thread(target=self.process).start()

    def process(self):
    """Runs the script and handles output/input"""
    self.popen = Popen(self.command, stdout=PIPE, stdin=PIPE, bufsize=1, text=True, shell=True)

    while self.running:
    self.execute()
    time.sleep(0.1) # Sleep to prevent busy waiting

    def execute(self):
    """Keeps inserting line by line into self.text the output of the execution of self.command"""
    if self.popen is not None:
    line = self.popen.stdout.readline() # Čtení řádku výstupu skriptu
    print(line)
    if line:
    # Vykreslení otázky a její zobrazení

    self.show(line.strip()) # Zobrazení výstupu
    self.text.update() # Aktualizace GUI, aby se výstup vykreslil okamžitě

    # Kontrola, zda výstup nevyžaduje vstup od uživatele
    if line.strip().endswith(":"): # Kontrola pro koncovou dvojtečku
    self.show("Waiting for input...") # Zobrazení zprávy "Čeká na vstup"
    self.input_entry.focus() # Přesunutí kurzoru do vstupního pole
    self.input_entry.update() # Aktualizace GUI pro vstupní pole

    # Kontrola, zda proces skončil
    if self.popen.poll() is not None:
    self.show(f"Process '{self.command}' terminated.\n\n")
    self.stop()


    def send_input(self, event=None):
    """Send input from Entry to the running process"""
    if self.popen and self.popen.stdin:
    user_input = self.input_entry.get() + "\n"
    self.popen.stdin.write(user_input)
    self.popen.stdin.flush() # Ensure input is sent immediately
    self.input_entry.delete(0, 'end') # Clear input field

    def stop(self):
    """Stops the running process if it's active"""
    if self.popen:
    try:
    self.popen.kill()
    except ProcessLookupError:
    pass
    self.running = False

    if __name__ == "__main__":
    root = tk.Tk()
    root.title("Console")
    console = Console(root)
    console.pack(expand=True, fill="both")

    root.mainloop()



    As you can see, I tried searching for input using ":" because my inputs end with ":". Thank you for your help

    Continue reading...

Compartilhe esta Página