spacr 0.1.7__py3-none-any.whl → 0.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- spacr/app_annotate.py +38 -527
- spacr/app_make_masks.py +30 -904
- spacr/core.py +21 -21
- spacr/deep_spacr.py +6 -6
- spacr/gui.py +38 -26
- spacr/gui_core.py +203 -109
- spacr/gui_elements.py +1185 -10
- spacr/gui_utils.py +186 -9
- spacr/measure.py +4 -4
- spacr/settings.py +282 -96
- spacr/utils.py +12 -15
- {spacr-0.1.7.dist-info → spacr-0.1.8.dist-info}/METADATA +1 -1
- {spacr-0.1.7.dist-info → spacr-0.1.8.dist-info}/RECORD +17 -17
- {spacr-0.1.7.dist-info → spacr-0.1.8.dist-info}/LICENSE +0 -0
- {spacr-0.1.7.dist-info → spacr-0.1.8.dist-info}/WHEEL +0 -0
- {spacr-0.1.7.dist-info → spacr-0.1.8.dist-info}/entry_points.txt +0 -0
- {spacr-0.1.7.dist-info → spacr-0.1.8.dist-info}/top_level.txt +0 -0
spacr/gui_core.py
CHANGED
@@ -1,29 +1,24 @@
|
|
1
|
-
import os, traceback, ctypes, matplotlib, requests, csv,
|
1
|
+
import os, traceback, ctypes, matplotlib, requests, csv, matplotlib, time, requests
|
2
|
+
import matplotlib.pyplot as plt
|
2
3
|
matplotlib.use('Agg')
|
3
4
|
import tkinter as tk
|
4
5
|
from tkinter import ttk
|
5
|
-
import tkinter.font as tkFont
|
6
6
|
from tkinter import filedialog
|
7
|
-
from
|
8
|
-
from multiprocessing import Process, Value, Queue
|
7
|
+
from multiprocessing import Process, Value, Queue, set_start_method
|
9
8
|
from multiprocessing.sharedctypes import Synchronized
|
10
|
-
from multiprocessing import set_start_method
|
11
9
|
from tkinter import ttk, scrolledtext
|
12
10
|
from matplotlib.figure import Figure
|
13
11
|
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
14
|
-
import time
|
15
|
-
import requests
|
16
12
|
from huggingface_hub import list_repo_files
|
17
13
|
|
18
|
-
from .settings import set_default_train_test_model, get_measure_crop_settings, set_default_settings_preprocess_generate_masks, get_analyze_reads_default_settings, set_default_umap_image_settings
|
19
|
-
from .gui_elements import create_menu_bar, spacrButton, spacrLabel, spacrFrame, spacrCheckbutton, spacrDropdownMenu ,set_dark_style, set_default_font
|
20
|
-
from . gui_run import run_mask_gui, run_measure_gui, run_classify_gui, run_sequencing_gui, run_umap_gui
|
21
|
-
|
22
14
|
try:
|
23
15
|
ctypes.windll.shcore.SetProcessDpiAwareness(True)
|
24
16
|
except AttributeError:
|
25
17
|
pass
|
26
18
|
|
19
|
+
from .settings import set_default_train_test_model, get_measure_crop_settings, set_default_settings_preprocess_generate_masks, get_analyze_reads_default_settings, set_default_umap_image_settings
|
20
|
+
from .gui_elements import create_menu_bar, spacrButton, spacrLabel, spacrFrame, spacrDropdownMenu ,set_dark_style, set_default_font
|
21
|
+
|
27
22
|
# Define global variables
|
28
23
|
q = None
|
29
24
|
console_output = None
|
@@ -46,26 +41,116 @@ def initiate_abort():
|
|
46
41
|
thread_control["run_thread"].join()
|
47
42
|
thread_control["run_thread"] = None
|
48
43
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
44
|
+
def spacrFigShow(fig_queue=None):
|
45
|
+
"""
|
46
|
+
Replacement for plt.show() that queues figures instead of displaying them.
|
47
|
+
"""
|
48
|
+
fig = plt.gcf()
|
49
|
+
if fig_queue:
|
50
|
+
fig_queue.put(fig)
|
51
|
+
else:
|
52
|
+
fig.show()
|
53
|
+
plt.close(fig)
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
def function_gui_wrapper(function=None, settings={}, q=None, fig_queue=None, imports=1):
|
56
|
+
|
57
|
+
"""
|
58
|
+
Wraps the run_multiple_simulations function to integrate with GUI processes.
|
59
|
+
|
60
|
+
Parameters:
|
61
|
+
- settings: dict, The settings for the run_multiple_simulations function.
|
62
|
+
- q: multiprocessing.Queue, Queue for logging messages to the GUI.
|
63
|
+
- fig_queue: multiprocessing.Queue, Queue for sending figures to the GUI.
|
64
|
+
"""
|
65
|
+
|
66
|
+
# Temporarily override plt.show
|
67
|
+
original_show = plt.show
|
68
|
+
plt.show = lambda: spacrFigShow(fig_queue)
|
69
|
+
|
70
|
+
try:
|
71
|
+
if imports == 1:
|
72
|
+
function(settings=settings)
|
73
|
+
elif imports == 2:
|
74
|
+
function(src=settings['src'], settings=settings)
|
75
|
+
except Exception as e:
|
76
|
+
# Send the error message to the GUI via the queue
|
77
|
+
errorMessage = f"Error during processing: {e}"
|
78
|
+
q.put(errorMessage)
|
79
|
+
traceback.print_exc()
|
80
|
+
finally:
|
81
|
+
# Restore the original plt.show function
|
82
|
+
plt.show = original_show
|
83
|
+
|
84
|
+
def run_function_gui(settings_type, settings, q, fig_queue, stop_requested):
|
85
|
+
from .gui_utils import process_stdout_stderr
|
86
|
+
from .core import preprocess_generate_masks, generate_ml_scores, identify_masks_finetune, check_cellpose_models, analyze_recruitment, train_cellpose, compare_cellpose_masks, analyze_plaques, generate_dataset, apply_model_to_tar
|
87
|
+
from .io import generate_cellpose_train_test
|
88
|
+
from .measure import measure_crop
|
89
|
+
from .sim import run_multiple_simulations
|
90
|
+
from .deep_spacr import train_test_model
|
91
|
+
from .sequencing import analyze_reads, map_barcodes_folder, perform_regression
|
92
|
+
process_stdout_stderr(q)
|
93
|
+
|
58
94
|
if settings_type == 'mask':
|
59
|
-
|
95
|
+
function = preprocess_generate_masks
|
96
|
+
imports = 2
|
60
97
|
elif settings_type == 'measure':
|
61
|
-
|
62
|
-
|
63
|
-
|
98
|
+
function = measure_crop
|
99
|
+
imports = 1
|
100
|
+
elif settings_type == 'simulation':
|
101
|
+
function = run_multiple_simulations
|
102
|
+
imports = 1
|
64
103
|
elif settings_type == 'sequencing':
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
104
|
+
function = analyze_reads
|
105
|
+
imports = 1
|
106
|
+
elif settings_type == 'classify':
|
107
|
+
function = train_test_model
|
108
|
+
imports = 2
|
109
|
+
elif settings_type == 'train_cellpose':
|
110
|
+
function = train_cellpose
|
111
|
+
imports = 1
|
112
|
+
elif settings_type == 'ml_analyze':
|
113
|
+
function = generate_ml_scores
|
114
|
+
imports = 2
|
115
|
+
elif settings_type == 'cellpose_masks':
|
116
|
+
function = identify_masks_finetune
|
117
|
+
imports = 1
|
118
|
+
elif settings_type == 'cellpose_all':
|
119
|
+
function = check_cellpose_models
|
120
|
+
imports = 1
|
121
|
+
elif settings_type == 'map_barcodes':
|
122
|
+
function = map_barcodes_folder
|
123
|
+
imports = 2
|
124
|
+
elif settings_type == 'regression':
|
125
|
+
function = perform_regression
|
126
|
+
imports = 2
|
127
|
+
elif settings_type == 'recruitment':
|
128
|
+
function = analyze_recruitment
|
129
|
+
imports = 2
|
130
|
+
#elif settings_type == 'cellpose_dataset':
|
131
|
+
# function = generate_cellpose_train_test
|
132
|
+
# imports = 1
|
133
|
+
#elif settings_type == 'plaques':
|
134
|
+
# function = analyze_plaques
|
135
|
+
# imports = 1
|
136
|
+
#elif settings_type == 'cellpose_compare':
|
137
|
+
# function = compare_cellpose_masks
|
138
|
+
# imports = 1
|
139
|
+
#elif settings_type == 'vision_scores':
|
140
|
+
# function = apply_model_to_tar
|
141
|
+
# imports = 1
|
142
|
+
#elif settings_type == 'vision_dataset':
|
143
|
+
# function = generate_dataset
|
144
|
+
# imports = 1
|
145
|
+
else:
|
146
|
+
raise ValueError(f"Invalid settings type: {settings_type}")
|
147
|
+
try:
|
148
|
+
function_gui_wrapper(function, settings, q, fig_queue, imports)
|
149
|
+
except Exception as e:
|
150
|
+
q.put(f"Error during processing: {e}")
|
151
|
+
traceback.print_exc()
|
152
|
+
finally:
|
153
|
+
stop_requested.value = 1
|
69
154
|
|
70
155
|
def start_process(q=None, fig_queue=None, settings_type='mask'):
|
71
156
|
global thread_control, vars_dict
|
@@ -85,25 +170,15 @@ def start_process(q=None, fig_queue=None, settings_type='mask'):
|
|
85
170
|
if thread_control.get("run_thread") is not None:
|
86
171
|
initiate_abort()
|
87
172
|
|
88
|
-
stop_requested = Value('i', 0)
|
173
|
+
stop_requested = Value('i', 0)
|
89
174
|
thread_control["stop_requested"] = stop_requested
|
90
175
|
|
91
|
-
process_args = (settings, q, fig_queue, stop_requested)
|
92
|
-
|
93
|
-
|
94
|
-
thread_control["run_thread"] = Process(target=run_mask_gui, args=process_args)
|
95
|
-
elif settings_type == 'measure':
|
96
|
-
thread_control["run_thread"] = Process(target=run_measure_gui, args=process_args)
|
97
|
-
elif settings_type == 'classify':
|
98
|
-
thread_control["run_thread"] = Process(target=run_classify_gui, args=process_args)
|
99
|
-
elif settings_type == 'sequencing':
|
100
|
-
thread_control["run_thread"] = Process(target=run_sequencing_gui, args=process_args)
|
101
|
-
elif settings_type == 'umap':
|
102
|
-
thread_control["run_thread"] = Process(target=run_umap_gui, args=process_args)
|
176
|
+
process_args = (settings_type, settings, q, fig_queue, stop_requested)
|
177
|
+
if settings_type in ['mask','measure','simulation','sequencing','classify','cellpose_dataset','train_cellpose','ml_analyze','cellpose_masks','cellpose_all','map_barcodes','regression','recruitment','plaques','cellpose_compare','vision_scores','vision_dataset']:
|
178
|
+
thread_control["run_thread"] = Process(target=run_function_gui, args=process_args)
|
103
179
|
else:
|
104
180
|
q.put(f"Error: Unknown settings type '{settings_type}'")
|
105
181
|
return
|
106
|
-
|
107
182
|
thread_control["run_thread"].start()
|
108
183
|
|
109
184
|
def import_settings(settings_type='mask'):
|
@@ -194,15 +269,19 @@ def convert_settings_dict_for_gui(settings):
|
|
194
269
|
variables[key] = ('entry', None, str(value))
|
195
270
|
return variables
|
196
271
|
|
197
|
-
def setup_settings_panel(vertical_container, settings_type='mask',
|
272
|
+
def setup_settings_panel(vertical_container, settings_type='mask', window_dimensions=[500, 1000]):
|
198
273
|
global vars_dict, scrollable_frame
|
199
|
-
from .settings import set_default_settings_preprocess_generate_masks, get_measure_crop_settings, set_default_train_test_model, get_analyze_reads_default_settings, set_default_umap_image_settings, generate_fields
|
274
|
+
from .settings import descriptions, get_identify_masks_finetune_default_settings, set_default_analyze_screen, set_default_settings_preprocess_generate_masks, get_measure_crop_settings, set_default_train_test_model, get_analyze_reads_default_settings, set_default_umap_image_settings, generate_fields, get_perform_regression_default_settings, get_train_cellpose_default_settings, get_map_barcodes_default_settings, get_analyze_recruitment_default_settings, get_check_cellpose_models_default_settings
|
275
|
+
|
276
|
+
width = (window_dimensions[0])//6
|
277
|
+
height = window_dimensions[1]
|
200
278
|
|
201
|
-
|
279
|
+
# Settings Frame
|
280
|
+
settings_frame = tk.Frame(vertical_container, bg='black', height=height, width=width)
|
202
281
|
vertical_container.add(settings_frame, stretch="always")
|
203
282
|
settings_label = spacrLabel(settings_frame, text="Settings", background="black", foreground="white", anchor='center', justify='center', align="center")
|
204
283
|
settings_label.grid(row=0, column=0, pady=10, padx=10)
|
205
|
-
scrollable_frame = spacrFrame(settings_frame, bg='black', width=
|
284
|
+
scrollable_frame = spacrFrame(settings_frame, bg='black', width=width)
|
206
285
|
scrollable_frame.grid(row=1, column=0, sticky="nsew")
|
207
286
|
settings_frame.grid_rowconfigure(1, weight=1)
|
208
287
|
settings_frame.grid_columnconfigure(0, weight=1)
|
@@ -217,9 +296,36 @@ def setup_settings_panel(vertical_container, settings_type='mask', frame_height=
|
|
217
296
|
settings = get_analyze_reads_default_settings(settings={})
|
218
297
|
elif settings_type == 'umap':
|
219
298
|
settings = set_default_umap_image_settings(settings={})
|
299
|
+
elif settings_type == 'train_cellpose':
|
300
|
+
settings = get_train_cellpose_default_settings(settings={})
|
301
|
+
elif settings_type == 'ml_analyze':
|
302
|
+
settings = set_default_analyze_screen(settings={})
|
303
|
+
elif settings_type == 'cellpose_masks':
|
304
|
+
settings = get_identify_masks_finetune_default_settings(settings={})
|
305
|
+
elif settings_type == 'cellpose_all':
|
306
|
+
settings = get_check_cellpose_models_default_settings(settings={})
|
307
|
+
elif settings_type == 'map_barcodes':
|
308
|
+
settings = get_map_barcodes_default_settings(settings={})
|
309
|
+
elif settings_type == 'regression':
|
310
|
+
settings = get_perform_regression_default_settings(settings={})
|
311
|
+
elif settings_type == 'recruitment':
|
312
|
+
settings = get_analyze_recruitment_default_settings(settings={})
|
313
|
+
#elif settings_type == 'simulation':
|
314
|
+
# settings = set_default_
|
315
|
+
#elif settings_type == 'cellpose_dataset':
|
316
|
+
# settings = set_default_
|
317
|
+
#elif settings_type == 'plaques':
|
318
|
+
# settings = set_default_
|
319
|
+
#elif settings_type == 'cellpose_compare':
|
320
|
+
# settings = set_default_
|
321
|
+
#elif settings_type == 'vision_scores':
|
322
|
+
# settings = set_default_
|
323
|
+
#elif settings_type == 'vision_dataset':
|
324
|
+
# settings = set_default_
|
220
325
|
else:
|
221
326
|
raise ValueError(f"Invalid settings type: {settings_type}")
|
222
327
|
|
328
|
+
|
223
329
|
variables = convert_settings_dict_for_gui(settings)
|
224
330
|
vars_dict = generate_fields(variables, scrollable_frame)
|
225
331
|
print("Settings panel setup complete")
|
@@ -353,18 +459,21 @@ def download_dataset(repo_id, subfolder, local_dir=None, retries=5, delay=5):
|
|
353
459
|
|
354
460
|
raise Exception("Failed to download files after multiple attempts.")
|
355
461
|
|
356
|
-
def setup_button_section(horizontal_container, settings_type='mask',
|
462
|
+
def setup_button_section(horizontal_container, settings_type='mask', window_dimensions=[500, 1000], run=True, abort=True, download=True, import_btn=True):
|
357
463
|
global button_frame, button_scrollable_frame, run_button, abort_button, download_dataset_button, import_button, q, fig_queue, vars_dict
|
464
|
+
from .settings import descriptions
|
465
|
+
|
466
|
+
width = (window_dimensions[0])//8
|
467
|
+
height = window_dimensions[1]
|
358
468
|
|
359
|
-
button_frame = tk.Frame(horizontal_container, bg='black')
|
469
|
+
button_frame = tk.Frame(horizontal_container, bg='black', height=height, width=width)
|
360
470
|
horizontal_container.add(button_frame, stretch="always", sticky="nsew")
|
361
471
|
button_frame.grid_rowconfigure(0, weight=0)
|
362
472
|
button_frame.grid_rowconfigure(1, weight=1)
|
363
473
|
button_frame.grid_columnconfigure(0, weight=1)
|
364
474
|
|
365
|
-
categories_label = spacrLabel(button_frame, text="Categories", background="black", foreground="white", font=('Helvetica', 12), anchor='center', justify='center', align="center")
|
475
|
+
categories_label = spacrLabel(button_frame, text="Categories", background="black", foreground="white", font=('Helvetica', 12), anchor='center', justify='center', align="center")
|
366
476
|
categories_label.grid(row=0, column=0, pady=10, padx=10)
|
367
|
-
|
368
477
|
button_scrollable_frame = spacrFrame(button_frame, bg='black')
|
369
478
|
button_scrollable_frame.grid(row=1, column=0, sticky="nsew")
|
370
479
|
|
@@ -393,6 +502,16 @@ def setup_button_section(horizontal_container, settings_type='mask', settings_ro
|
|
393
502
|
# Call toggle_settings after vars_dict is initialized
|
394
503
|
if vars_dict is not None:
|
395
504
|
toggle_settings(button_scrollable_frame)
|
505
|
+
|
506
|
+
# Description frame
|
507
|
+
description_frame = tk.Frame(horizontal_container, bg='black', height=height, width=width)
|
508
|
+
horizontal_container.add(description_frame, stretch="always", sticky="nsew")
|
509
|
+
description_frame.grid_columnconfigure(0, weight=1) # Make the column stretch
|
510
|
+
description_label = tk.Label(description_frame, text="Module Description", bg='black', fg='white', anchor='nw', justify='left', wraplength=width-50)
|
511
|
+
description_label.grid(row=0, column=0, pady=50, padx=20, sticky='nsew') # Use sticky='nsew' to stretch the label
|
512
|
+
description_text = descriptions.get(settings_type, "No description available for this module.")
|
513
|
+
description_label.config(text=description_text)
|
514
|
+
|
396
515
|
return button_scrollable_frame
|
397
516
|
|
398
517
|
def hide_all_settings(vars_dict, categories):
|
@@ -529,80 +648,55 @@ def setup_frame(parent_frame):
|
|
529
648
|
return parent_frame, vertical_container, horizontal_container
|
530
649
|
|
531
650
|
def initiate_root(parent, settings_type='mask'):
|
532
|
-
|
651
|
+
global q, fig_queue, parent_frame, scrollable_frame, button_frame, vars_dict, canvas, canvas_widget, progress_label, progress_output, button_scrollable_frame
|
652
|
+
from .gui_utils import main_thread_update_function
|
653
|
+
from .gui import gui_app
|
533
654
|
set_start_method('spawn', force=True)
|
534
|
-
|
535
|
-
def main_thread_update_function(root, q, fig_queue, canvas_widget, progress_label):
|
536
|
-
try:
|
537
|
-
ansi_escape_pattern = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
|
538
|
-
while not q.empty():
|
539
|
-
message = q.get_nowait()
|
540
|
-
clean_message = ansi_escape_pattern.sub('', message)
|
541
|
-
if clean_message.startswith("Progress"):
|
542
|
-
progress_label.config(text=clean_message)
|
543
|
-
if clean_message.startswith("\rProgress"):
|
544
|
-
progress_label.config(text=clean_message)
|
545
|
-
elif clean_message.startswith("Successfully"):
|
546
|
-
progress_label.config(text=clean_message)
|
547
|
-
elif clean_message.startswith("Processing"):
|
548
|
-
progress_label.config(text=clean_message)
|
549
|
-
elif clean_message.startswith("scale"):
|
550
|
-
pass
|
551
|
-
elif clean_message.startswith("plot_cropped_arrays"):
|
552
|
-
pass
|
553
|
-
elif clean_message == "" or clean_message == "\r" or clean_message.strip() == "":
|
554
|
-
pass
|
555
|
-
else:
|
556
|
-
print(clean_message)
|
557
|
-
except Exception as e:
|
558
|
-
print(f"Error updating GUI canvas: {e}")
|
559
|
-
finally:
|
560
|
-
root.after(100, lambda: main_thread_update_function(root, q, fig_queue, canvas_widget, progress_label))
|
561
|
-
|
562
|
-
global q, fig_queue, parent_frame, scrollable_frame, button_frame, vars_dict, canvas, canvas_widget, progress_label, button_scrollable_frame
|
563
655
|
print("Initializing root with settings_type:", settings_type)
|
656
|
+
|
564
657
|
parent_frame = parent
|
658
|
+
parent_frame.update_idletasks()
|
659
|
+
frame_width = int(parent_frame.winfo_width())
|
660
|
+
frame_height = int(parent_frame.winfo_height())
|
661
|
+
print(frame_width, frame_height)
|
662
|
+
dims = [frame_width, frame_height]
|
565
663
|
|
566
664
|
if not hasattr(parent_frame, 'after_tasks'):
|
567
665
|
parent_frame.after_tasks = []
|
568
666
|
|
667
|
+
# Clear previous content instead of destroying the root
|
569
668
|
for widget in parent_frame.winfo_children():
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
print(f"Error destroying widget: {e}")
|
669
|
+
try:
|
670
|
+
widget.destroy()
|
671
|
+
except tk.TclError as e:
|
672
|
+
print(f"Error destroying widget: {e}")
|
575
673
|
|
576
674
|
q = Queue()
|
577
675
|
fig_queue = Queue()
|
578
676
|
parent_frame, vertical_container, horizontal_container = setup_frame(parent_frame)
|
579
|
-
scrollable_frame, vars_dict = setup_settings_panel(horizontal_container, settings_type) # Adjust height and width as needed
|
580
|
-
button_scrollable_frame = setup_button_section(horizontal_container, settings_type)
|
581
|
-
canvas, canvas_widget = setup_plot_section(vertical_container)
|
582
|
-
console_output = setup_console(vertical_container)
|
583
677
|
|
584
|
-
if settings_type
|
585
|
-
|
678
|
+
if settings_type == 'annotate':
|
679
|
+
from .app_annotate import initiate_annotation_app
|
680
|
+
initiate_annotation_app(horizontal_container)
|
681
|
+
elif settings_type == 'make_masks':
|
682
|
+
from .app_make_masks import initiate_make_mask_app
|
683
|
+
initiate_make_mask_app(horizontal_container)
|
586
684
|
else:
|
587
|
-
|
685
|
+
scrollable_frame, vars_dict = setup_settings_panel(horizontal_container, settings_type, window_dimensions=dims)
|
686
|
+
button_scrollable_frame = setup_button_section(horizontal_container, settings_type, window_dimensions=dims)
|
687
|
+
canvas, canvas_widget = setup_plot_section(vertical_container)
|
688
|
+
console_output = setup_console(vertical_container)
|
689
|
+
|
690
|
+
if settings_type in ['mask', 'measure', 'classify', 'sequencing']:
|
691
|
+
progress_output = setup_progress_frame(vertical_container)
|
692
|
+
else:
|
693
|
+
progress_output = None
|
694
|
+
|
695
|
+
set_globals(q, console_output, parent_frame, vars_dict, canvas, canvas_widget, scrollable_frame, progress_label, fig_queue)
|
696
|
+
process_console_queue()
|
697
|
+
process_fig_queue()
|
698
|
+
after_id = parent_frame.after(100, lambda: main_thread_update_function(parent_frame, q, fig_queue, canvas_widget, progress_label))
|
699
|
+
parent_frame.after_tasks.append(after_id)
|
588
700
|
|
589
|
-
set_globals(q, console_output, parent_frame, vars_dict, canvas, canvas_widget, scrollable_frame, progress_label, fig_queue)
|
590
|
-
process_console_queue()
|
591
|
-
process_fig_queue()
|
592
|
-
after_id = parent_frame.after(100, lambda: main_thread_update_function(parent_frame, q, fig_queue, canvas_widget, progress_label))
|
593
|
-
parent_frame.after_tasks.append(after_id)
|
594
701
|
print("Root initialization complete")
|
595
702
|
return parent_frame, vars_dict
|
596
|
-
|
597
|
-
def start_gui_app(settings_type='mask'):
|
598
|
-
global q, fig_queue, parent_frame, scrollable_frame, vars_dict, canvas, canvas_widget, progress_label
|
599
|
-
root = tk.Tk()
|
600
|
-
width = root.winfo_screenwidth()
|
601
|
-
height = root.winfo_screenheight()
|
602
|
-
root.geometry(f"{width}x{height}")
|
603
|
-
root.title(f"SpaCr: {settings_type.capitalize()}")
|
604
|
-
root.content_frame = tk.Frame(root)
|
605
|
-
print("Starting GUI app with settings_type:", settings_type)
|
606
|
-
initiate_root(root.content_frame, settings_type)
|
607
|
-
create_menu_bar(root)
|
608
|
-
root.mainloop()
|