How to run a cancellable function when a new Tkinter window opens

green and gold eggs and ham

In tkinter, I would like to create the following:

When the button foo is pressed, the function foo begins running immediately. A new window will pop up with a a "cancel" button that lets the user terminate the process midway through (as my actual process can take up to 30 minutes). If foo runs to completion, the window closes itself and notifies the user that the process completed.

Here is code that demonstrates my toy problem:

from tkinter import ttk, messagebox, Toplevel, Tk
import time
import multiprocessing

def foo():
    for i in range(100):
        print(i)
        time.sleep(0.1)

class TerminatedProcess(Exception):
    def __init__(self, str = "Process was terminated"):
        self.error_str = str

class ProcessWindow(Toplevel):
    def __init__(self, parent, process):
        Toplevel.__init__(self, parent)
        self.parent = parent
        self. process = process

        terminate_button = ttk.Button(self, text="Cancel", command=self.cancel)
        terminate_button.grid(row=0, column=0)

        self.grab_set() # so you can't push submit multiple times

    def cancel(self):
        self.process.terminate()
        self.destroy()
        raise TerminatedProcess

    def launch(self):
        self.process.start()
        self.process.join()
        self.destroy()

class MainApplication(ttk.Frame):
    def __init__(self, parent, *args, **kwargs):
        ttk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent

        self.button = ttk.Button(self, text = "foo", command = self.callback)
        self.button.grid(row = 0, column = 0)

    def callback(self):
        try:
            proc = multiprocessing.Process(target=foo)
            process_window = ProcessWindow(self, proc)
            process_window.launch()
        except TerminatedProcess as e: # raised if foo is cancelled in other window
            messagebox.showinfo(title="Cancelled", message=e.error_str)
        else:
            messagebox.showinfo(message="sucessful run", title="Finished")

def main():
    root = Tk()
    my_app = MainApplication(root, padding=(4))
    my_app.grid(column=0, row=0)
    root.mainloop()

if __name__ == '__main__':
    main()

With this code, when the button foo is pressed, process_window is indeed made because the the function foo runs, and I get a "run successful" dialogue box, but the window never pops up! This is a problem because the user needs to have the option of terminating foo. Interestingly enough, If I delete process_window.launch(), I will still get the "run successful" message (as expected), but the process_window shows up.

I have tried putting the launch command inside the initialization, but that made the window not show up, either.

I also tried starting the process outside the window declaration as follows:

proc.start()
process_window = ProcessWindow(self, proc)
proc.join()

The window still failed to show up, but the process ran.

My question is, how do I need to arrange these pieces to generate the ProcessWindow AND automatically start the process when the ProcessWindow opens?

UPDATE (workaround): I am aware that I could create a start button inside the ProcessWindow that would run the function (and then disable the button after it had been pressed once), but I would still like to know how to implement what was described in the original question.

Stevo Mitric

Perhaps you are looking for something like this:

from tkinter import ttk, messagebox, Toplevel, Tk
import time
import multiprocessing

def foo():
    for i in range(100):
        print(i)
        time.sleep(0.1)

class ProcessWindow(Toplevel):
    def __init__(self, parent, process):
        Toplevel.__init__(self, parent)
        self.parent = parent
        self.process = process

        terminate_button = ttk.Button(self, text="Cancel", command=self.cancel)
        terminate_button.grid(row=0, column=0)

        self.grab_set() # so you can't push submit multiple times

    def cancel(self):
        self.process.terminate()
        self.destroy()
        messagebox.showinfo(title="Cancelled", message='Process was terminated')

    def launch(self):
        self.process.start()
        self.after(10, self.isAlive)            # Starting the loop to check when the process is going to end

    def isAlive(self):
        if self.process.is_alive():                     # Process still running
            self.after(100, self.isAlive)               # Going again...
        elif self:
            # Process finished
            messagebox.showinfo(message="sucessful run", title="Finished")
            self.destroy()

class MainApplication(ttk.Frame):
    def __init__(self, parent, *args, **kwargs):
        ttk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent

        self.button = ttk.Button(self, text = "foo", command = self.callback)
        self.button.grid(row = 0, column = 0)

    def callback(self):
        proc = multiprocessing.Process(target=foo)
        process_window = ProcessWindow(self, proc)
        process_window.launch()

def main():
    root = Tk()
    my_app = MainApplication(root, padding=(4))
    my_app.grid(column=0, row=0)
    root.mainloop()

if __name__ == '__main__':
    main()

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How to run a function in new process?

From Dev

showModalDialog; Opens a New Window in IE

From Dev

Tkinter; how to use scrollbar in a popup/top-level window that opens when a button is pressed in main root window

From Dev

Autoclose buffer occupying Vim's preview window when new buffer opens in preview window

From Dev

Python. Selenium. How to wait for new window opens?

From Dev

Fancybox opens new window

From Dev

JTable opens in a new window even when inside JPanel?

From Dev

In a Firefox restartless add-on, how do I run code when a new window opens (listen for window open)?

From Dev

JWT: how to handle GET requests when user opens a new tab?

From Dev

Why python executable opens new window instance when function by multiprocessing module is called on windows

From Dev

How do I control where CKEditor API opens a new new window for the filebrowserBrowseUrl?

From Dev

Run a specified function when the user opens a new tab in Chromium

From Dev

How to split a new window and run a command in this new window using tmux?

From Dev

Tkinter widgets lost information when I open a new instance of their window

From Dev

how to make only 1 new window when a button is clicked? tkinter

From Dev

How can I customize the window that opens when starting a command from the Windows "Run" command?

From Dev

Autoclose buffer occupying Vim's preview window when new buffer opens in preview window

From Dev

Error message when opening new window in Tkinter

From Dev

Python Tkinter: How do I apply a new background image when opening a new tk window?

From Dev

When I run WinSat.exe from the command line, it opens a new terminal window

From Dev

Passing a JavaScript function to run in a new window object

From Dev

Onsubmit event opens new window

From Dev

I want to run a function when ever the form is clicked on taskbar and it opens

From Dev

New window opens incorrectly

From Dev

How do I control where CKEditor API opens a new new window for the filebrowserBrowseUrl?

From Dev

Run a specified function when the user opens a new tab in Chromium

From Dev

How to split a new window and run a command in this new window using tmux?

From Dev

Text opens in wrong window tkinter

From Dev

Tkinter new window

Related Related

  1. 1

    How to run a function in new process?

  2. 2

    showModalDialog; Opens a New Window in IE

  3. 3

    Tkinter; how to use scrollbar in a popup/top-level window that opens when a button is pressed in main root window

  4. 4

    Autoclose buffer occupying Vim's preview window when new buffer opens in preview window

  5. 5

    Python. Selenium. How to wait for new window opens?

  6. 6

    Fancybox opens new window

  7. 7

    JTable opens in a new window even when inside JPanel?

  8. 8

    In a Firefox restartless add-on, how do I run code when a new window opens (listen for window open)?

  9. 9

    JWT: how to handle GET requests when user opens a new tab?

  10. 10

    Why python executable opens new window instance when function by multiprocessing module is called on windows

  11. 11

    How do I control where CKEditor API opens a new new window for the filebrowserBrowseUrl?

  12. 12

    Run a specified function when the user opens a new tab in Chromium

  13. 13

    How to split a new window and run a command in this new window using tmux?

  14. 14

    Tkinter widgets lost information when I open a new instance of their window

  15. 15

    how to make only 1 new window when a button is clicked? tkinter

  16. 16

    How can I customize the window that opens when starting a command from the Windows "Run" command?

  17. 17

    Autoclose buffer occupying Vim's preview window when new buffer opens in preview window

  18. 18

    Error message when opening new window in Tkinter

  19. 19

    Python Tkinter: How do I apply a new background image when opening a new tk window?

  20. 20

    When I run WinSat.exe from the command line, it opens a new terminal window

  21. 21

    Passing a JavaScript function to run in a new window object

  22. 22

    Onsubmit event opens new window

  23. 23

    I want to run a function when ever the form is clicked on taskbar and it opens

  24. 24

    New window opens incorrectly

  25. 25

    How do I control where CKEditor API opens a new new window for the filebrowserBrowseUrl?

  26. 26

    Run a specified function when the user opens a new tab in Chromium

  27. 27

    How to split a new window and run a command in this new window using tmux?

  28. 28

    Text opens in wrong window tkinter

  29. 29

    Tkinter new window

HotTag

Archive