From 38e1956850006f51aa88b465712510a11bdd56d9 Mon Sep 17 00:00:00 2001 From: "Tu, Ethan" <tuethan@msu.edu> Date: Wed, 15 Apr 2020 20:03:07 -0400 Subject: [PATCH] Delete pk_gui.ipynb --- Examples/pk_gui.ipynb | 652 ------------------------------------------ 1 file changed, 652 deletions(-) delete mode 100644 Examples/pk_gui.ipynb diff --git a/Examples/pk_gui.ipynb b/Examples/pk_gui.ipynb deleted file mode 100644 index e6c24ef..0000000 --- a/Examples/pk_gui.ipynb +++ /dev/null @@ -1,652 +0,0 @@ -#!/usr/bin/env python -# coding: utf-8 - -"""pk_GUI is a tool to compare, optimize, and visualize - two compartment models of perfusion kinetics""" -### import everything -import glob -import pathlib -import os -import tkinter as tk -from tkinter import Button, Label, ttk, Frame, StringVar, Scale, Grid, Entry, Tk -import numpy as np -import matplotlib.pyplot as plt - -from scipy.integrate import solve_ivp -from matplotlib.backends.backend_tkagg import ( - FigureCanvasTkAgg, NavigationToolbar2Tk) -# Implement the default Matplotlib key bindings. -from matplotlib.backend_bases import key_press_handler -from matplotlib.figure import Figure -from pk_two_comp import pk_two_comp as pk2c - - -class StartPage(): - """The StartPage class is the first page of the pk_GUI application. - It has 4 buttons: Compare, Optimize, Visualize, and Exit Application. - Each button will create a new window leading to the specified action. - Exit will exit the whole application. - """ - - def __init__(self, root): - """Initializing the class with tkinter window object root - Parameters - ---------- - root : tkinter object - The Window which will show the application - Attributes - ----------- - optimize_btn : tkinter button - Clicking on the button leads to the optimizer application - compare_btn : tkinter button - Clicking on the button leads to the compare application. - visualize_btn : tkinter button - Clicking on the button leads to the vizualize application. - quitMainWindow : tkinter button - Clicking ont he button closes and exits the application. - """ - self.root = root - self.root.title('PK Optimizer Tool') - - # Calculating the center - width = self.root.winfo_reqwidth() - height = self.root.winfo_reqheight() - wids = self.root.winfo_screenwidth() - heights = self.root.winfo_screenheight() - xval = (wids/2) - (width/2) - yval = (heights/2) - (height/2) - self.root.geometry('+%d+%d' % (xval, yval)) - - # Making buttons - self.label = Label(self.root, - text="Please choose what application you'd like to explore: ", - width=30, wraplength=200) - self.label.grid(column=1, row=0, sticky='nwes') - self.compare_btn = Button( - self.root, text="Compare!", command=self.compare) - self.compare_btn.grid(column=1, row=1, sticky='nwes') - - self.optimize_btn = Button( - self.root, text="Optimize!", command=self.optimize) - self.optimize_btn.grid(column=1, row=2, sticky='nwes') - - self.visualize_btn = Button( - self.root, text="Visualize!", command=self.visualize) - self.visualize_btn.grid(column=1, row=3, sticky='nwes') - - self.quit = Button( - self.root, text="Exit Application", command=self.on_cancel) - self.quit.grid(column=1, row=4, sticky='nwes') - - def compare(self): - """Opens compare function.""" - my_gui = PkCompare(self) - - def optimize(self): - """Opens optimizer function.""" - my_gui = PkOptimize(self) - - def visualize(self): - """Opens visualize function.""" - my_gui = PkVisualize(self) - - def on_cancel(self): - """Exits and closes window""" - self.root.destroy() - -class PkOptimize(tk.Toplevel): - """Initializes the pk_optimize application GUI""" - def __init__(self, parent): # , master_root): - """Initializes the pk_optimize application GUI - User selects a dataset from the dropdown box. - Pressing the load button will plot the data selected. - Once data is loaded, give your initial guesses for parameter values. - Press Optimize button, and the optimal values will be outputted. - - Attributes - ----------- - wd : path - Absolute path name to current directory. Defaults to ./Data - filename : string - Name of the data file you'd like to access - time : double[] - list of all timepoints - aorta : double[] - concentration of tracer in aorta (input function) - myo : double[] - concentration of tracer in myocardial tissue (conc_isf) - Flow : double - Flow is the flow of plasma through the blood vessel in mL/(mL*min). Defaults to 1/60. - Vp : double - Vp is the volume of plasma in mL. Defaults to 0.05. - Visf : double - Visf is the volume of interstitial fluid in mL. Defaults to 0.15. - PS : double - PS is the permeability-surface area constant in mL/(g*min). Defaults to 1/60. - ymax : int - Magnitude of Gamma-var peak. - tmax : double - Time of which highest peak in Gamma-var appears - alpha : double - Scale factor - delay : double - Delay to start Gamma-var curve. - - """ - super().__init__(name='pk Optimizer tool') - self.parent = parent - - # Making mainfraim to center the window to the screen - mainframe = ttk.Frame(self) - #mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) - mainframe.columnconfigure(0, weight=1) - mainframe.rowconfigure(0, weight=1) - - # Calculating the center - width = 1100 - height = 600 - wids = self.winfo_screenwidth() - heights = self.winfo_screenheight() - xval = (wids/2) - (width/2) - yval = (heights/2) - (height/2) - self.geometry('+%d+%d' % (xval, yval)) - - self.pk = pk2c() - self.geometry('1100x600') - self.frame1 = Frame(self) - self.frame2 = Frame(self, padx=10) - self.frame3 = Frame(self) - self.frame4 = Frame(self) - self.frame5 = Frame(self) - self.frame1.grid(column=0, row=1) - self.frame2.grid(column=0, row=0) - self.frame3.grid(column=2, row=1) - self.frame4.grid(column=2, row=0) - self.frame5.grid(column=1, row=0) - - if os.path.basename(os.path.normpath(pathlib.Path().absolute())) != 'Data': - os.chdir(pathlib.Path('Data').absolute()) - - # Get lists of files - self.filenames = glob.glob('*.{}'.format('csv')) - # Combobox creation - self.chosen_file = tk.StringVar() - self.file_combobox = ttk.Combobox( - self.frame5, width=20, textvariable=self.chosen_file) - - # Adding combobox drop down list - self.file_combobox['values'] = self.filenames - self.file_combobox.grid(column=0, row=1) - self.file_combobox.current(0) - - # Creating blank canvas to plot input function on - self.fig1 = plt.figure(figsize=(4.5, 4.5), dpi=100) - plt.ylabel("Mass of Tracer (mg)") - plt.xlabel("Time (sec)") - - self.canvas1 = FigureCanvasTkAgg(self.fig1, master=self.frame2) - self.canvas1.get_tk_widget().grid(row=0, column=0) - self.canvas1.draw() - - # Creating blank canvas to plot output function on - self.fig2 = plt.figure(figsize=(4.5, 4.5), dpi=100) - plt.ylabel("Mass of Tracer (mg)") - plt.xlabel("Time (sec)") - - self.canvas2 = FigureCanvasTkAgg(self.fig2, master=self.frame4) - self.canvas2.get_tk_widget().grid(row=0, column=0) - self.canvas2.draw() - - # Creating a bunch of labels and input boxes for initial guesses for parameters - self.ymax_lbl = Label(self.frame1, text="ymax guess: ") - self.ymax_lbl.grid(column=0, row=0) - self.tmax_lbl = Label(self.frame1, text="tmax guess: ") - self.tmax_lbl.grid(column=0, row=1) - self.alpha_lbl = Label(self.frame1, text="alpha guess: ") - self.alpha_lbl.grid(column=0, row=2) - self.delay_lbl = Label(self.frame1, text="delay guess: ") - self.delay_lbl.grid(column=0, row=3) - - self.ymax_input = Entry(self.frame1, width=50) - self.ymax_input.grid(column=1, row=0) - self.tmax_input = Entry(self.frame1, width=50) - self.tmax_input.grid(column=1, row=1) - self.alpha_input = Entry(self.frame1, width=50) - self.alpha_input.grid(column=1, row=2) - self.delay_input = Entry(self.frame1, width=50) - self.delay_input.grid(column=1, row=3) - - self.ymax_opt_lbl = Label(self.frame1) - self.ymax_opt_lbl.grid(column=2, row=0) - self.tmax_opt_lbl = Label(self.frame1) - self.tmax_opt_lbl.grid(column=2, row=1) - self.alpha_opt_lbl = Label(self.frame1) - self.alpha_opt_lbl.grid(column=2, row=2) - self.delay_opt_lbl = Label(self.frame1) - self.delay_opt_lbl.grid(column=2, row=3) - - self.flow_lbl = Label(self.frame3, text="flow guess: ") - self.flow_lbl.grid(column=0, row=0) - self.visf_lbl = Label(self.frame3, text="visf guess: ") - self.visf_lbl.grid(column=0, row=1) - self.baseline_lbl = Label(self.frame3, text="baseline guess: ") - self.baseline_lbl.grid(column=0, row=2) - - self.flow_input = Entry(self.frame3, width=50) - self.flow_input.grid(column=1, row=0) - self.visf_input = Entry(self.frame3, width=50) - self.visf_input.grid(column=1, row=1) - self.baseline_input = Entry(self.frame3, width=50) - self.baseline_input.grid(column=1, row=2) - - self.flow_opt_lbl = Label(self.frame3) - self.flow_opt_lbl.grid(column=2, row=0) - self.visf_opt_lbl = Label(self.frame3) - self.visf_opt_lbl.grid(column=2, row=1) - self.baseline_opt_lbl = Label(self.frame3) - self.baseline_opt_lbl.grid(column=2, row=2) - - # Creating buttons to load data and perform optimization - self.load_btn_text = tk.StringVar() - self.load_btn = Button( - master=self.frame5, textvariable=self.load_btn_text, command=self.load_data) - self.load_btn_text.set("Load") - self.load_btn.grid(column=0, row=2) - - self.opt_btn_text = tk.StringVar() - self.opt_btn = Button( - master=self.frame5, textvariable=self.opt_btn_text, command=self.perform_opt) - self.opt_btn_text.set("Perform Optimization") - self.opt_btn.grid(column=0, row=3) - - # Creating button to go back to main page - self.back_btn = Button( - master=self.frame5, text="Go Back", command=self.go_back) - self.back_btn.grid(column=0, row=4) - -# #------------------------------------------------------------- -# #------------------------------------------------------------- -# #------------------------------------------------------------- - - def load_data(self): - """Loads in the data selected in the combobox.""" - - file = self.file_combobox.get() - self.pk.get_data(file) - - self.fig1.add_subplot(111).plot(self.pk.time, self.pk.aorta, 'bo') - plt.ylabel("Mass of Tracer (mg)") - plt.xlabel("Time (sec)") - self.fig1.canvas.draw() - - self.fig2.add_subplot(111).plot(self.pk.time, self.pk.myo, 'ro') - plt.ylabel("Mass of Tracer (mg)") - plt.xlabel("Time (sec)") - self.canvas2.draw_idle() - - def perform_opt(self): - """Performs the optimization using the values taken from input boxes as inital guesses.""" - - # Performs function fitting, outputs optimized parameters in opt - opt = self.pk.input_func_fit([self.ymax_input.get(), self.tmax_input.get(), - self.alpha_input.get(), self.delay_input.get()]) - - # Shows opt in new labels - self.ymax_opt_lbl.configure(text=opt[0]) - self.tmax_opt_lbl.configure(text=opt[1]) - self.alpha_opt_lbl.configure(text=opt[2]) - self.delay_opt_lbl.configure(text=opt[3]) - - # Plots fitted gamma_var curve - self.fig1.add_subplot(111).plot(np.arange(0, 25, 0.01), - self.pk.gamma_var(np.arange(0, 25, 0.01), - opt[0], opt[1], opt[2], opt[3]), 'k-') - self.canvas1.draw_idle() - - # Performs function fitting, outputs optimized parameters in opt - opt = self.pk.output_func_fit([self.flow_input.get(), - self.visf_input.get(), self.baseline_input.get()]) - - # Shows opt in new labels - self.flow_opt_lbl.configure(text=opt[0]) - self.visf_opt_lbl.configure(text=opt[1]) - self.baseline_opt_lbl.configure(text=opt[2]) - - # Plots fitted gamma_var curve - deriv_sol = solve_ivp(self.pk.derivs, [0, 30], - [0, 0], t_eval=self.pk.time) - fit_myo = deriv_sol.y[0] + deriv_sol.y[1] - self.fig2.add_subplot(111).plot(self.pk.time, fit_myo + opt[2], 'm-') - self.canvas2.draw_idle() - - def go_back(self): - """Closes the optimize application and leads you to the start page""" - self.destroy() - - -class PkCompare(tk.Toplevel): - """Initializes the pkCompare application GUI""" - def __init__(self, parent): # , master_root): - """Initializes the pk_compare application GUI - User can select a dataset from the dropdown menu and plot it. - Plotting multiple datasets will overlay them. - Navigation bar is provided to zoom in/out of the plot. - """ - super().__init__(name='pk Optimizer tool') - self.parent = parent - self.legend = [] - - # Making mainfraim to center the window to the screen - mainframe = ttk.Frame(self) - #mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) - mainframe.columnconfigure(0, weight=1) - mainframe.rowconfigure(0, weight=1) - - width = 1100 - height = 500 - wids = self.winfo_screenwidth() - heights = self.winfo_screenheight() - xval = (wids/2) - (width/2) - yval = (heights/2) - (height/2) - self.geometry('+%d+%d' % (xval, yval)) - - self.pk = pk2c() - self.geometry('1100x500') - self.frame1 = Frame(self) - self.frame2 = Frame(self, padx=10) - self.frame3 = Frame(self) - self.frame4 = Frame(self) - self.frame5 = Frame(self) - self.frame6 = Frame(self) - self.frame7 = Frame(self) - self.frame1.grid(column=0, row=2) - self.frame2.grid(column=0, row=1) - self.frame3.grid(column=2, row=2) - self.frame4.grid(column=2, row=1) - self.frame5.grid(column=1, row=1) - self.frame6.grid(column=0, row=0) - self.frame7.grid(column=2, row=0) - - if os.path.basename(os.path.normpath(pathlib.Path().absolute())) != 'Data': - os.chdir(pathlib.Path('Data').absolute()) - - # Get lists of files - self.filenames = glob.glob('*.{}'.format('csv')) - # Combobox creation - self.chosen_file = tk.StringVar() - self.file_combobox = ttk.Combobox( - self.frame5, width=20, textvariable=self.chosen_file) - - # Adding combobox drop down list - self.file_combobox['values'] = self.filenames - self.file_combobox.grid(column=0, row=1) - self.file_combobox.current(0) - - # Creating blank canvas to plot input function on - self.fig1 = plt.figure(figsize=(4.5, 4.5), dpi=100) - plt.ylabel("Mass of Tracer (mg)") - plt.xlabel("Time (sec)") - - self.canvas1 = FigureCanvasTkAgg(self.fig1, master=self.frame2) - self.canvas1.get_tk_widget().grid(row=0, column=0) - self.canvas1.draw() - toolbar = NavigationToolbar2Tk(self.canvas1, self.frame6) - toolbar.update() - - # Creating blank canvas to plot output function on - self.fig2 = plt.figure(figsize=(4.5, 4.5), dpi=100) - plt.ylabel("Mass of Tracer (mg)") - plt.xlabel("Time (sec)") - - self.canvas2 = FigureCanvasTkAgg(self.fig2, master=self.frame4) - self.canvas2.get_tk_widget().grid(row=0, column=0) - self.canvas2.draw() - toolbar = NavigationToolbar2Tk(self.canvas2, self.frame7) - toolbar.update() - - # Creating buttons to load data and perform optimization - self.load_btn_text = tk.StringVar() - self.load_btn = Button( - master=self.frame5, textvariable=self.load_btn_text, command=self.load_data) - self.load_btn_text.set("Load") - self.load_btn.grid(column=0, row=2) - - # Creating button to go back to main page - self.back_btn = Button( - master=self.frame5, text="Go Back", command=self.go_back) - self.back_btn.grid(column=0, row=4) - -# #------------------------------------------------------------- -# #------------------------------------------------------------- -# #------------------------------------------------------------- - - def load_data(self): - """Loads in the data selected in the combobox.""" - file = self.file_combobox.get() - self.legend.append(file) - self.pk.time = [] - self.pk.aorta = [] - self.pk.myo = [] - self.pk.get_data(file) - - self.fig1.add_subplot(111).plot(self.pk.time, self.pk.aorta) - plt.ylabel("Mass of Tracer (mg)") - plt.xlabel("Time (sec)") - self.fig1.canvas.draw() - - self.fig2.add_subplot(111).plot(self.pk.time, self.pk.myo) - plt.ylabel("Mass of Tracer (mg)") - plt.xlabel("Time (sec)") - self.canvas2.draw_idle() - - plt.legend(self.legend) - - def go_back(self): - """Exits the compare window and goes back to the start page.""" - self.destroy() - -# ==================================================================== - - -class PkVisualize(tk.Toplevel): - """Initializes the pkVisualize application GUI""" - def __init__(self, parent): # , master_root): - """Initializes the pk_visualize application GUI - User can select a dataset from the dropdown menu and load it. - Plotting multiple datasets will overlay them. - Navigation bar is provided to zoom in/out of the plot. - Using the sliders to change parameter values will result in different - Cin and Cout curves. You must hit plot after every change to see it. - """ - - super().__init__(name='pk Optimizer tool') - self.parent = parent - - # Making mainfraim to center the window to the screen - mainframe = ttk.Frame(self) - mainframe.columnconfigure(0, weight=1) - mainframe.rowconfigure(0, weight=1) - - # Calculating the center - width = 1280 - height = 500 - wids = self.winfo_screenwidth() - heights = self.winfo_screenheight() - xval = (wids/2) - (width/2) - yval = (heights/2) - (height/2) - self.geometry('+%d+%d' % (xval, yval)) - - self.pk = pk2c() - self.geometry('1280x500') - self.frame1 = Frame(self) - self.frame2 = Frame(self) - self.frame3 = Frame(self) - self.frame4 = Frame(self) - self.frame5 = Frame(self) - - self.frame1.grid(column=1, row=0) - self.frame2.grid(column=1, row=1) - self.frame3.grid(column=2, row=1) - self.frame4.grid(column=3, row=0) - self.frame5.grid(column=3, row=1) - - if os.path.basename(os.path.normpath(pathlib.Path().absolute())) != 'Data': - os.chdir(pathlib.Path('Data').absolute()) - - # Get lists of files - self.filenames = glob.glob('*.{}'.format('csv')) - # Combobox creation - self.chosen_file = tk.StringVar() - self.file_combobox = ttk.Combobox( - self.frame3, width=20, textvariable=self.chosen_file) - - # Adding combobox drop down list - self.file_combobox['values'] = self.filenames - self.file_combobox.grid(column=1, row=0) - self.file_combobox.current(0) - - # Creating blank canvas to plot input function on - self.fig1 = plt.figure(figsize=(4.5, 4.5), dpi=100) - plt.ylabel("Mass of Tracer (mg)") - plt.xlabel("Time (sec)") - - # Creating blank canvas to plot output function on - self.fig2 = plt.figure(figsize=(4.5, 4.5), dpi=100) - plt.ylabel("Mass of Tracer (mg)") - plt.xlabel("Time (sec)") - - self.canvas1 = FigureCanvasTkAgg(self.fig1, master=self.frame2) - self.canvas1.get_tk_widget().grid(row=0, column=0) - self.canvas1.draw() - toolbar = NavigationToolbar2Tk(self.canvas1, self.frame1) - toolbar.update() - - self.canvas2 = FigureCanvasTkAgg(self.fig2, master=self.frame5) - self.canvas2.get_tk_widget().grid(row=0, column=0) - self.canvas2.draw() - toolbar = NavigationToolbar2Tk(self.canvas2, self.frame4) - toolbar.update() - - # Creating a bunch of labels and input boxes for initial guesses for parameters - self.ymax_lbl = Label(self.frame3, text="ymax: ") - self.ymax_lbl.grid(column=0, row=1) - self.tmax_lbl = Label(self.frame3, text="tmax: ") - self.tmax_lbl.grid(column=0, row=2) - self.alpha_lbl = Label(self.frame3, text="alpha: ") - self.alpha_lbl.grid(column=0, row=3) - self.delay_lbl = Label(self.frame3, text="delay: ") - self.delay_lbl.grid(column=0, row=4) - - self.ymax_slider = Scale( - self.frame3, from_=10, to=500, orient='horizontal', length=250, resolution=1) - self.ymax_slider.set(250) - self.ymax_slider.grid(column=1, row=1) - self.tmax_slider = Scale( - self.frame3, from_=0.0, to=20, orient='horizontal', length=250, resolution=0.5) - self.tmax_slider.set(6) - self.tmax_slider.grid(column=1, row=2) - self.alpha_slider = Scale( - self.frame3, from_=0, to=10, orient='horizontal', length=250, resolution=0.25) - self.alpha_slider.set(2) - self.alpha_slider.grid(column=1, row=3) - self.delay_slider = Scale( - self.frame3, from_=0, to=10, orient='horizontal', length=250, resolution=1) - self.delay_slider.set(0) - self.delay_slider.grid(column=1, row=4) - - self.flow_lbl = Label(self.frame3, text="flow:") - self.flow_lbl.grid(column=0, row=6) - self.visf_lbl = Label(self.frame3, text="visf:") - self.visf_lbl.grid(column=0, row=7) - self.baseline_lbl = Label(self.frame3, text="baseline: ") - self.baseline_lbl.grid(column=0, row=8) - - self.flow_slider = Scale( - self.frame3, from_=0, to=.1, orient='horizontal', length=250, resolution=0.0025) - self.flow_slider.set(0.03) - self.flow_slider.grid(column=1, row=6) - self.visf_slider = Scale( - self.frame3, from_=0, to=10, length=250, orient='horizontal', resolution=0.1) - self.visf_slider.set(2) - self.visf_slider.grid(column=1, row=7) - self.baseline_slider = Scale( - self.frame3, from_=20, to=80, length=250, orient='horizontal', resolution=1) - self.baseline_slider.set(50) - self.baseline_slider.grid(column=1, row=8) - - # Creating buttons to load data and perform optimization - self.load_btn_text = tk.StringVar() - self.load_btn = Button( - master=self.frame3, textvariable=self.load_btn_text, command=self.load_data, padx=15) - self.load_btn_text.set("Load") - self.load_btn.grid(column=2, row=0) - - self.opt_btn_text = tk.StringVar() - self.opt_btn = Button( - master=self.frame3, textvariable=self.opt_btn_text, command=self.plot) - self.opt_btn_text.set("Plot") - self.opt_btn.grid(column=2, row=3) - - # Creating button to go back to main page - self.back_btn = Button( - master=self.frame3, text="Go Back", command=self.go_back) - self.back_btn.grid(column=1, row=9) - -# #------------------------------------------------------------- -# #------------------------------------------------------------- -# #------------------------------------------------------------- - def plot(self): - """Plots Cin and Cout curve using parameters given from sliders.""" - file = self.file_combobox.get() - self.pk.get_data(file) - - self.pk.ymax = self.ymax_slider.get() - self.pk.tmax = self.tmax_slider.get() - self.pk.alpha = self.alpha_slider.get() - self.pk.delay = self.delay_slider.get() - - self.fig1.add_subplot(111).plot(np.arange(0, 25, 0.01), - self.pk.gamma_var(np.arange(0, 25, 0.01), - self.ymax_slider.get(), - self.tmax_slider.get(), - self.alpha_slider.get(), - self.delay_slider.get()), 'k-') - - self.fig1.canvas.draw() - self.pk.flow = self.flow_slider.get() - self.pk.visf = self.visf_slider.get() - self.pk.baseline = self.baseline_slider.get() - - # Plots fitted gamma_var curve - deriv_sol = solve_ivp(self.pk.derivs, [0, 30], - [0, 0], t_eval=self.pk.time) - fit_myo = deriv_sol.y[0] + deriv_sol.y[1] - self.fig2.add_subplot(111).plot( - self.pk.time, fit_myo + self.pk.baseline, 'm-') - self.canvas2.draw_idle() - - def load_data(self): - """Loads in the data selected in the combobox.""" - file = self.file_combobox.get() - self.pk.get_data(file) - - self.fig1.add_subplot(111).plot(self.pk.time, self.pk.aorta, 'bo') - plt.ylabel("Mass of Tracer (mg)") - plt.xlabel("Time (sec)") - self.fig1.canvas.draw() - - self.fig2.add_subplot(111).plot(self.pk.time, self.pk.myo, 'ro') - plt.ylabel("Mass of Tracer (mg)") - plt.xlabel("Time (sec)") - self.canvas2.draw_idle() - - def go_back(self): - """Exits the compare window and goes back to the start page.""" - self.destroy() - - -# ================================================================================================= -if __name__ == "__main__": - MainWindow = Tk() - gui = StartPage(MainWindow) - MainWindow.mainloop() \ No newline at end of file -- GitLab