'Tkinter closing immediatly after plot

I am creating an interface using Tkinter to plot signals from a database. I am using Python 3.8 and PyCharm 2021.2.1.

The interface is supposed to open another window (from the menubar on top) where all data file indices are displayed and from there when one data index is selected is plotted on the main window. The problem is as soon as the plot is done the mainloop ends. I can see the plot actually drawn on the canvas during debug, so I know that it is plotted, but afterwards I don't understand why it's closing the mainloop.

There are no error messages.

The main window is not supposed to close itself after the plot.

import os
import random
import sys

import scipy.signal as signal
import tkinter as tk
from tkinter import ttk

import numpy as np
import re
import scipy.io as sio

from matplotlib import pyplot as plt, image as mpimg
from matplotlib.backends._backend_tk import NavigationToolbar2Tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.cm import ScalarMappable
from matplotlib.figure import Figure

import tools.patient
import tools.biosemi
import tools.signal_avg
import tools.ecg_tools

import platform
import time
from tkinter.filedialog import askopenfilename


class main_interface():

    def __init__(self):

        print(platform.python_version())

        # region init
        if re.split('-', platform.platform())[0] == 'Windows':
            self.root_path = 'S:'
        elif re.split('-', platform.platform())[0] == 'macOS':
            self.root_path = '/Volumes/Signal'


        # region Main window
        self.root = tk.Tk()
        self.root.wm_title("Embedding in Tk")
        self.root.geometry("1000x750")

        self.root.columnconfigure(tuple(range(42)), weight=1)
        self.root.rowconfigure(tuple(range(34)), weight=1)

        self.root.protocol("WM_DELETE_WINDOW", lambda: _quit(self.root))


        menubar = tk.Menu(self.root, tearoff=False)
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(label="Load pickle", command=lambda: popup_load_BS(self, "Load pickle"))
        menubar.add_cascade(label="File", menu=filemenu)
        # endregion

        # region Tabs menu
        self.tabsystem = ttk.Notebook(self.root)

        tab1 = tk.Frame(self.tabsystem)

        self.tabsystem.add(tab1, text='Raw Data')
        self.tabsystem.grid(row=1, column=0, rowspan=32, columnspan=42, sticky='news')


        self.root.config(menu=menubar)
        # endregion

        ############################################### region Tab 1 : Raw Data ###############################################
        tab1.columnconfigure(tuple(range(40)), weight=1)
        tab1.rowconfigure(tuple(range(30)), weight=1)

        fig = Figure()
        self.raw_data_ax = fig.add_subplot(111)

        self.raw_data_canvas = FigureCanvasTkAgg(fig, master=tab1)  # A tk.DrawingArea.
        self.raw_data_canvas.draw()
        self.raw_data_canvas.get_tk_widget().grid(row=1, column=1, columnspan=39 - 1, rowspan=18 - 1, sticky='news')

        ###############    TOOLBAR    ###############
        toolbarFrame = tk.Frame(master=tab1)
        toolbarFrame.grid(row=30, column=0, columnspan=39, sticky='sw')
        toolbar = NavigationToolbar2Tk(self.raw_data_canvas, toolbarFrame)

        self.zoom_value = tk.IntVar(toolbarFrame)
        toolbar.children['!checkbutton2'].config(variable=self.zoom_value, onvalue=1, offvalue=0)


        self.root.mainloop()


####################### region function for raw data tab #############################


def popup_load_BS(self, txt):
    def select_BS(self, event, window, txt, tree):

        item = tree.selection()
        # print(item)
        selection = tree.item(item)['values'][0]
        # print(selection)
        msg = f'Load {selection}?'
        res = tk.messagebox.askquestion('Load BS Data', msg)

        if res == 'yes':
            if txt == "Load raw bdf":
                print('BDF loaded ')
            elif txt == "Load pickle":
                print('Pickle loaded')
            window.quit()
            window.destroy()
            # plot data

            l = [random.randint(0, 10) for index in range(100)]
            self.raw_data_ax.plot(l)
            self.raw_data_canvas.draw()

            print('plotted')

    popup_root = tk.Toplevel()
    popup_root.grab_set()
    popup_root.columnconfigure(tuple(range(1)), weight=1)
    popup_root.rowconfigure(tuple(range(1)), weight=1)
    popup_root.geometry('1000x500')

    tree = ttk.Treeview(popup_root, column=("c1"), show='headings', height=1, selectmode="browse")

    tree.column("# 1", anchor='center')
    tree.heading("# 1", text="BS")
    for i in range(1,10):
        tree.insert('', i, values=('BS00'+str(i)))

    tree.grid(row=0, column=0, sticky='news')

    scroll = ttk.Scrollbar(popup_root, orient="vertical", command=tree.yview)
    scroll.grid(row=0, column=1, sticky='news')
    tree.configure(yscrollcommand=scroll.set)



    # THE ISSUE SEEMS TO BE HERE
    load_button = tk.Button(master=popup_root, text="Load")
    load_button.config(command=lambda: select_BS(self, [], popup_root, txt,tree))
    load_button.grid(row=1, column=0, columnspan=2, sticky='news')

    tree.bind("<Double-1>", lambda event: select_BS(self, event, popup_root, txt, tree))

def _quit(root):
    root.quit()  # stops mainloop
    root.destroy()  # this is necessary on Windows to prevent
                    # Fatal Python Error: PyEval_RestoreThread: NULL tstate


# endregion

if __name__ == '__main__':

    BS_data = main_interface()
    print('mainloop ended')
    # BS_data.mainloop()

The issue seems to be around the part of the code where the data index is selected by either pressing the Load button or at the bind with the double click (just before the _quit function)



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source