1

I'm using python 3 and tkinter. I have a simple GUI that triggers a back-end process (in a different class, instantiated in the GUI class). I want to display a message to the user once the back-end process is complete, i.e. use messagebox (or anything else, doesn't really matter) but only after the process is complete. How can I do that?

Thanks in advance

6
  • 1
    The question seems rather vague. The simple answer to "how do I display a message after a process completes" is "wait for the process to complete and then display the message". What part are you having trouble with? The waiting, or the displaying? Have you tried using the messagebox? Commented Jun 19, 2017 at 18:36
  • Hi @BryanOakley, I'm trying to figure out how to trigger the message display and where in the tKinter class should the messagebox be placed so that it opens only after it is triggered. Commented Jun 19, 2017 at 19:53
  • Is the back-end process executed in a different thread? We need more information about your problem to answer your question. Commented Jun 20, 2017 at 13:12
  • @j_4321 The back-end process is executed in the same thread (at least I haven't defined multi-threading). It is called by a different class in a different file. The GUI class instantiates the back-end class and calls its appropriate functions once buttons are pressed. I can set a flag once the back-end process is done, question is how do I trigger the GUI class to display a message once this flag is set. Commented Jun 20, 2017 at 17:54
  • You can use after to check periodically if the "finished" flag has been set and then display the messagebox. Commented Jun 20, 2017 at 18:25

1 Answer 1

3

If the process blocks the main loop while it is executed, you can just create a method in your main class that runs the process and shows the messagebox:

import tkinter as tk
from tkinter import messagebox
import time


class BackendProcess:
    def __init__(self):
        self.finished = False

    def run(self):
        time.sleep(10)
        self.finished = True


class GUI(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.process = BackendProcess()
        tk.Button(self, text='Run', command=self.run).pack()

    def run(self):
        self.process.run() 
        messagebox.showinfo('Info', 'Process completed!')


if __name__ == '__main__':
    gui = GUI()
    gui.mainloop()

If the process does not block the main loop, then the above method does not work and the messagebox is displayed right after the start of the process. To avoid this, the after method can be used to periodically check the finished flag of the process:

import tkinter as tk
from tkinter import messagebox
import time
import threading


class BackendProcess:
    def __init__(self):
        self.finished = False

    def task(self):
        time.sleep(2)
        print('finished')
        self.finished = True

    def run(self):
        thread = threading.Thread(target=self.task, daemon=True)
        thread.start()


class GUI(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.process = BackendProcess()
        tk.Button(self, text='Run', command=self.run).pack()

    def run(self):
        self.process.run()
        self.check_process()

    def check_process(self):
        """ Check every 1000 ms whether the process is finished """
        if self.process.finished:
            messagebox.showinfo('Info', 'Process completed')
        else:
            self.after(1000, self.check_process)


if __name__ == '__main__':
    gui = GUI()
    gui.mainloop()

From the comments, I think the first method should work since the process is executed in the main thread. I have shown the second case anyway because completion notification are especially useful for time-consuming tasks that are often executed in a separated thread to avoid freezing the GUI.

Sign up to request clarification or add additional context in comments.

2 Comments

Regarding your second method, instead of checking every second, is it possible to send/trigger an event? I think that may be cleaner
@NagabhushanSN I don't know how thread safe it is to trigger an event from the thread. It seems to work when I launch the program from the command line but in the python interpreter I get RuntimeError: main thread is not in main loop. On the other hand, polling the thread regularly is the solution I have seen the most often, though I agree it is not ideal.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.