Thomas Weeks
Thomas Weeks

Reputation: 83

Stopping script with Stop button in Pycharm IDE throws KeyboardInterrupt Error

I created a window using Tkinter. When I press the stop button (the red square) on the pycharm IDE, the program stops (that's good) and I get an error message (that's bad):

Traceback (most recent call last):
  File "C:/Users/toman/klusterbox/playground/a.py", line 52, in <module>
    win.finish()  # update and mainloop the window
  File "C:/Users/toman/klusterbox/playground/a.py", line 37, in finish
    mainloop()
  File "C:\Program Files\Python37\lib\tkinter\__init__.py", line 560, in mainloop
    _default_root.tk.mainloop(n)
KeyboardInterrupt

I'm running the following python script which is ready to run:

from tkinter import *


class MakeWindow:  # builds a window object
    def __init__(self):
        self.topframe = Frame(root)  # creates a frame
        self.s = Scrollbar(self.topframe)  # scrollbar
        self.c = Canvas(self.topframe, width=1600)  # canvas
        self.body = Frame(self.c)  # creates a frame on the canvas
        self.buttons = Canvas(self.topframe)  # creates a frame for buttons

    def create(self, frame):
        if frame is not None:
            frame.destroy()  # close out the previous frame
        self.topframe.pack(fill=BOTH, side=LEFT)
        self.buttons.pack(fill=BOTH, side=BOTTOM)
        # link up the canvas and scrollbar
        self.s.pack(side=RIGHT, fill=BOTH)
        self.c.pack(side=LEFT, fill=BOTH)
        self.s.configure(command=self.c.yview, orient="vertical")
        self.c.configure(yscrollcommand=self.s.set)
        # link the mousewheel - implementation varies by platform
        if sys.platform == "win32":
            self.c.bind_all('<MouseWheel>', lambda event: self.c.yview_scroll
            (int(mousewheel * (event.delta / 120)), "units"))
        elif sys.platform == "darwin":
            self.c.bind_all('<MouseWheel>', lambda event: self.c.yview_scroll
            (int(mousewheel * event.delta), "units"))
        elif sys.platform == "linux":
            self.c.bind_all('<Button-4>', lambda event: self.c.yview('scroll', -1, 'units'))
            self.c.bind_all('<Button-5>', lambda event: self.c.yview('scroll', 1, 'units'))
        self.c.create_window((0, 0), window=self.body, anchor=NW)

    def finish(self):  # This closes the window created by front_window()
        root.update()
        self.c.config(scrollregion=self.c.bbox("all"))
        mainloop()


root = Tk()  # define root
position_x = 100  # initialize position and size for root window
position_y = 50
size_x = 625
size_y = 600
root.geometry("%dx%d+%d+%d" % (size_x, size_y, position_x, position_y))  # implements the size for the window
mousewheel = -1  # configure direction of mousewheel as reverse ( 1 for natural)
win = MakeWindow()  # create window object
win.create(None)  # build the window
for i in range(50):
    Label(win.body, text=i).pack()  # fill the window with numbers
Button(win.buttons, text="Quit", width=20, command=lambda: root.destroy()).pack(side=LEFT)  # create a quit button
win.finish()  # update and mainloop the window

I've been working on this program for a while and I don't remember getting the error message until recently. Is it possible the IDE configurations got changed somehow? Note that the error message doesn't occur when I hit the "quit" button or when i close the window with the "x" on the top right hand corner of the window. In that case I get:

Process finished with exit code 0

Is this supposed to be happening or am I missing something?

edit: On the suggestion of Sujay, I used try/except. Changing the finish method fixed the problem.

    def finish(self):  # This closes the window created by front_window()
        root.update()
        self.c.config(scrollregion=self.c.bbox("all"))
        try:
            mainloop()
        except KeyboardInterrupt:
            root.destroy()

Upvotes: 0

Views: 773

Answers (1)

user15801675
user15801675

Reputation:

Quoting from the Python Docs:

Raised when the user hits the interrupt key (normally Control-C or Delete). During execution, a check for interrupts is made regularly. The exception inherits from BaseException so as to not be accidentally caught by code that catches Exception and thus prevent the interpreter from exiting.

Since it is a sort of exception, you can use try...except

try:
    from tkinter import *

    .....
    .....

    Button(win.buttons, text="Quit", width=20, command=lambda: 
    root.destroy()).pack(side=LEFT)  # create a quit button
    win.finish()  # update and mainloop the window
except KeyboardInterrupt:
    root.destroy()

Upvotes: 1

Related Questions