spacr 0.0.21__py3-none-any.whl → 0.0.35__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/gui_mask_app.py CHANGED
@@ -4,7 +4,6 @@ from tkinter import ttk, scrolledtext
4
4
  from ttkthemes import ThemedTk
5
5
  from matplotlib.figure import Figure
6
6
  from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
7
- from matplotlib.figure import Figure
8
7
  matplotlib.use('Agg')
9
8
  from tkinter import filedialog
10
9
  from multiprocessing import Process, Queue, Value
@@ -16,18 +15,40 @@ except AttributeError:
16
15
  pass
17
16
 
18
17
  from .logger import log_function_call
19
- from .gui_utils import ScrollableFrame, StdoutRedirector, clear_canvas, main_thread_update_function, create_dark_mode, set_dark_style, generate_fields, process_stdout_stderr, set_default_font, style_text_boxes
20
- from .gui_utils import mask_variables, check_mask_gui_settings, preprocess_generate_masks_wrapper, read_settings_from_csv, update_settings_from_csv#, toggle_advanced_settings
18
+ from .gui_utils import ScrollableFrame, StdoutRedirector, ToggleSwitch, CustomButton
19
+ from .gui_utils import clear_canvas, main_thread_update_function, set_dark_style, generate_fields, process_stdout_stderr, set_default_font, style_text_boxes
20
+ from .gui_utils import mask_variables, check_mask_gui_settings, preprocess_generate_masks_wrapper, read_settings_from_csv, update_settings_from_csv, create_menu_bar
21
21
 
22
22
  thread_control = {"run_thread": None, "stop_requested": False}
23
23
 
24
+ def toggle_test_mode():
25
+ global vars_dict
26
+ current_state = vars_dict['test_mode'][2].get()
27
+ new_state = not current_state
28
+ vars_dict['test_mode'][2].set(new_state)
29
+ if new_state:
30
+ test_mode_button.config(bg="blue")
31
+ else:
32
+ test_mode_button.config(bg="gray")
33
+
24
34
  def toggle_advanced_settings():
25
- advanced = advanced_var.get()
26
- for widget in advanced_widgets:
27
- if advanced:
28
- widget.grid()
35
+ global vars_dict
36
+
37
+ timelapse_settings = ['timelapse', 'timelapse_memory', 'timelapse_remove_transient', 'timelapse_mode', 'timelapse_objects', 'timelapse_displacement', 'timelapse_frame_limits', 'fps']
38
+ misc_settings = ['examples_to_plot', 'all_to_mip', 'pick_slice', 'skip_mode']
39
+ opperational_settings = ['preprocess', 'masks', 'randomize', 'batch_size', 'custom_regex', 'merge', 'normalize_plots', 'workers', 'plot', 'remove_background', 'lower_quantile']
40
+
41
+ advanced_settings = timelapse_settings+misc_settings+opperational_settings
42
+
43
+ # Toggle visibility of advanced settings
44
+ for setting in advanced_settings:
45
+ label, widget, var = vars_dict[setting]
46
+ if advanced_var.get() is False:
47
+ label.grid_remove() # Hide the label
48
+ widget.grid_remove() # Hide the widget
29
49
  else:
30
- widget.grid_remove()
50
+ label.grid() # Show the label
51
+ widget.grid() # Show the widget
31
52
 
32
53
  @log_function_call
33
54
  def initiate_abort():
@@ -40,24 +61,20 @@ def initiate_abort():
40
61
  if thread_control["run_thread"].is_alive():
41
62
  thread_control["run_thread"].terminate()
42
63
  thread_control["run_thread"] = None
43
-
64
+
44
65
  @log_function_call
45
66
  def run_mask_gui(q, fig_queue, stop_requested):
46
67
  global vars_dict
47
68
  process_stdout_stderr(q)
48
69
  try:
49
70
  settings = check_mask_gui_settings(vars_dict)
50
- #settings = add_mask_gui_defaults(settings)
51
- #for key in settings:
52
- # value = settings[key]
53
- # print(key, value, type(value))
54
71
  preprocess_generate_masks_wrapper(settings, q, fig_queue)
55
72
  except Exception as e:
56
73
  q.put(f"Error during processing: {e}")
57
74
  traceback.print_exc()
58
75
  finally:
59
76
  stop_requested.value = 1
60
-
77
+
61
78
  @log_function_call
62
79
  def start_process(q, fig_queue):
63
80
  global thread_control
@@ -68,152 +85,138 @@ def start_process(q, fig_queue):
68
85
  thread_control["stop_requested"] = stop_requested
69
86
  thread_control["run_thread"] = Process(target=run_mask_gui, args=(q, fig_queue, stop_requested))
70
87
  thread_control["run_thread"].start()
71
-
88
+
72
89
  def import_settings(scrollable_frame):
73
90
  global vars_dict
74
91
 
75
92
  csv_file_path = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])
76
93
  csv_settings = read_settings_from_csv(csv_file_path)
77
94
  variables = mask_variables()
78
- #variables = add_mask_gui_defaults(variables)
79
95
  new_settings = update_settings_from_csv(variables, csv_settings)
80
96
  vars_dict = generate_fields(new_settings, scrollable_frame)
81
-
97
+
82
98
  @log_function_call
83
- def initiate_mask_root(width, height):
84
- global root, vars_dict, q, canvas, fig_queue, canvas_widget, thread_control, advanced_widgets, advanced_var
85
-
86
- theme = 'breeze'
87
-
88
- if theme in ['clam']:
89
- root = tk.Tk()
90
- style = ttk.Style(root)
91
- style.theme_use(theme) #plastik, clearlooks, elegance, default was clam #alt, breeze, arc
92
- set_dark_style(style)
93
- elif theme in ['breeze']:
94
- root = ThemedTk(theme="breeze")
95
- style = ttk.Style(root)
96
- set_dark_style(style)
97
-
99
+ def initiate_mask_root(parent_frame, width, height):
100
+ global vars_dict, q, canvas, fig_queue, canvas_widget, thread_control, advanced_var, scrollable_frame
101
+
102
+ style = ttk.Style(parent_frame)
103
+ set_dark_style(style)
98
104
  style_text_boxes(style)
99
- set_default_font(root, font_name="Arial", size=8)
100
- #root.state('zoomed') # For Windows to maximize the window
101
- root.attributes('-fullscreen', True)
102
- root.geometry(f"{width}x{height}")
103
- root.title("SpaCer: generate masks")
105
+ set_default_font(parent_frame, font_name="Open Sans", size=8)
106
+ parent_frame.configure(bg='black')
107
+ parent_frame.grid_rowconfigure(0, weight=1)
108
+ parent_frame.grid_columnconfigure(0, weight=1)
109
+
104
110
  fig_queue = Queue()
105
-
111
+
106
112
  def _process_fig_queue():
107
113
  global canvas
108
114
  try:
109
115
  while not fig_queue.empty():
110
116
  clear_canvas(canvas)
111
117
  fig = fig_queue.get_nowait()
112
- #set_fig_text_properties(fig, font_size=8)
113
118
  for ax in fig.get_axes():
114
119
  ax.set_xticks([]) # Remove x-axis ticks
115
120
  ax.set_yticks([]) # Remove y-axis ticks
116
121
  ax.xaxis.set_visible(False) # Hide the x-axis
117
122
  ax.yaxis.set_visible(False) # Hide the y-axis
118
- #ax.title.set_fontsize(14)
119
- #disable_interactivity(fig)
120
123
  fig.tight_layout()
121
- fig.set_facecolor('#333333')
124
+ fig.set_facecolor('black')
122
125
  canvas.figure = fig
123
126
  fig_width, fig_height = canvas_widget.winfo_width(), canvas_widget.winfo_height()
124
127
  fig.set_size_inches(fig_width / fig.dpi, fig_height / fig.dpi, forward=True)
125
- canvas.draw_idle()
128
+ canvas.draw_idle()
126
129
  except Exception as e:
127
130
  traceback.print_exc()
128
- #pass
129
131
  finally:
130
132
  canvas_widget.after(100, _process_fig_queue)
131
-
132
- # Process queue for console output
133
+
133
134
  def _process_console_queue():
134
135
  while not q.empty():
135
136
  message = q.get_nowait()
136
137
  console_output.insert(tk.END, message)
137
138
  console_output.see(tk.END)
138
139
  console_output.after(100, _process_console_queue)
139
-
140
- # Vertical container for settings and console
141
- vertical_container = tk.PanedWindow(root, orient=tk.HORIZONTAL) #VERTICAL
142
- vertical_container.pack(fill=tk.BOTH, expand=True)
143
140
 
144
- # Scrollable Frame for user settings
145
- scrollable_frame = ScrollableFrame(vertical_container, bg='#333333')
146
- vertical_container.add(scrollable_frame, stretch="always")
147
-
148
- # Setup for user input fields (variables)
141
+ vertical_container = tk.PanedWindow(parent_frame, orient=tk.HORIZONTAL)
142
+ vertical_container.grid(row=0, column=0, sticky=tk.NSEW)
143
+ parent_frame.grid_rowconfigure(0, weight=1)
144
+ parent_frame.grid_columnconfigure(0, weight=1)
145
+
146
+ # Settings Section
147
+ settings_frame = tk.Frame(vertical_container, bg='black')
148
+ vertical_container.add(settings_frame, stretch="always")
149
+ settings_label = ttk.Label(settings_frame, text="Settings", style="Custom.TLabel")
150
+ settings_label.grid(row=0, column=0, pady=10, padx=10)
151
+ scrollable_frame = ScrollableFrame(settings_frame, width=600)
152
+ scrollable_frame.grid(row=1, column=0, sticky="nsew")
153
+ settings_frame.grid_rowconfigure(1, weight=1)
154
+ settings_frame.grid_columnconfigure(0, weight=1)
155
+
156
+ # Create advanced settings checkbox
157
+ advanced_var = tk.BooleanVar(value=False)
158
+ advanced_Toggle = ToggleSwitch(scrollable_frame.scrollable_frame, text="Advanced Settings", variable=advanced_var, command=toggle_advanced_settings)
159
+ advanced_Toggle.grid(row=48, column=0, pady=10, padx=10)
149
160
  variables = mask_variables()
150
161
  vars_dict = generate_fields(variables, scrollable_frame)
151
- #del vars_dict['fps']
152
-
153
- # Debugging: print vars_dict to ensure it is populated correctly
154
- #print("vars_dict:", vars_dict)
162
+ toggle_advanced_settings()
163
+ vars_dict['Test mode'] = (None, None, tk.BooleanVar(value=False))
155
164
 
156
- # Horizontal container for Matplotlib figure and the vertical pane (for settings and console)
157
- horizontal_container = tk.PanedWindow(vertical_container, orient=tk.VERTICAL) #HORIZONTAL
158
- vertical_container.add(horizontal_container, stretch="always")
159
-
160
- # Matplotlib figure setup
161
- figure = Figure(figsize=(30, 4), dpi=100, facecolor='#333333')
165
+ # Button section
166
+ test_mode_button = CustomButton(scrollable_frame.scrollable_frame, text="Test Mode", command=toggle_test_mode)
167
+ test_mode_button.grid(row=47, column=1, pady=10, padx=10)
168
+ import_btn = CustomButton(scrollable_frame.scrollable_frame, text="Import Settings", command=lambda: import_settings(scrollable_frame))
169
+ import_btn.grid(row=47, column=0, pady=20, padx=20)
170
+ run_button = CustomButton(scrollable_frame.scrollable_frame, text="Run", command=lambda: start_process(q, fig_queue))
171
+ run_button.grid(row=45, column=0, pady=20, padx=20)
172
+ abort_button = CustomButton(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort)
173
+ abort_button.grid(row=45, column=1, pady=20, padx=20)
174
+ progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Processing: 0%", background="black", foreground="white") # Create progress field
175
+ progress_label.grid(row=50, column=0, columnspan=2, sticky="ew", pady=(5, 0), padx=10)
176
+
177
+ # Plot Canvas Section
178
+ plot_frame = tk.PanedWindow(vertical_container, orient=tk.VERTICAL) # Horizontal container for Matplotlib figure and the vertical pane (for settings and console)
179
+ vertical_container.add(plot_frame, stretch="always")
180
+ figure = Figure(figsize=(30, 4), dpi=100, facecolor='black') # Matplotlib figure setup
162
181
  plot = figure.add_subplot(111)
163
182
  plot.plot([], []) # This creates an empty plot.
164
183
  plot.axis('off')
165
-
166
- # Embedding the Matplotlib figure in the Tkinter window
167
- canvas = FigureCanvasTkAgg(figure, master=horizontal_container)
168
- canvas.get_tk_widget().configure(cursor='arrow', background='#333333', highlightthickness=0)
169
- #canvas.get_tk_widget().configure(cursor='arrow')
184
+ canvas = FigureCanvasTkAgg(figure, master=plot_frame) # Embedd Matplotlib figure in Tkinter window
185
+ canvas.get_tk_widget().configure(cursor='arrow', background='black', highlightthickness=0)
170
186
  canvas_widget = canvas.get_tk_widget()
171
- horizontal_container.add(canvas_widget, stretch="always")
187
+ plot_frame.add(canvas_widget, stretch="always")
172
188
  canvas.draw()
173
189
  canvas.figure = figure
174
190
 
175
- # Console output setup below the settings
176
- console_output = scrolledtext.ScrolledText(vertical_container, height=10)
177
- vertical_container.add(console_output, stretch="always")
191
+ # Console Section
192
+ console_frame = tk.Frame(vertical_container, bg='black')
193
+ vertical_container.add(console_frame, stretch="always")
194
+ console_label = ttk.Label(console_frame, text="Console", background="black", foreground="white")
195
+ console_label.grid(row=0, column=0, pady=10, padx=10)
196
+ console_output = scrolledtext.ScrolledText(console_frame, height=10, bg='black', fg='white', insertbackground='white')
197
+ console_output.grid(row=1, column=0, sticky="nsew")
198
+ console_frame.grid_rowconfigure(1, weight=1)
199
+ console_frame.grid_columnconfigure(0, weight=1)
178
200
 
179
- # Queue and redirection setup for updating console output safely
180
201
  q = Queue()
181
202
  sys.stdout = StdoutRedirector(console_output)
182
203
  sys.stderr = StdoutRedirector(console_output)
183
204
 
184
- advanced_var = tk.BooleanVar()
185
- advanced_checkbox = ttk.Checkbutton(scrollable_frame.scrollable_frame, text="Advanced Settings", variable=advanced_var, command=toggle_advanced_settings)
186
- advanced_checkbox.grid(row=46, column=1, pady=10, padx=10)
187
-
188
- # This is your GUI setup where you create the Run button
189
- run_button = ttk.Button(scrollable_frame.scrollable_frame, text="Run",command=lambda: start_process(q, fig_queue))
190
- run_button.grid(row=45, column=0, pady=10, padx=10)
191
-
192
- abort_button = ttk.Button(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort)
193
- abort_button.grid(row=45, column=1, pady=10, padx=10)
194
-
195
- progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Processing: 0%", background="#333333", foreground="white")
196
- progress_label.grid(row=41, column=0, columnspan=2, sticky="ew", pady=(5, 0), padx=10)
197
-
198
- # Create the Import Settings button
199
- import_btn = tk.Button(root, text="Import Settings", command=lambda: import_settings(scrollable_frame))
200
- import_btn.pack(pady=20, padx=10)
201
-
202
-
203
-
204
205
  _process_console_queue()
205
206
  _process_fig_queue()
206
- create_dark_mode(root, style, console_output)
207
-
208
- root.after(100, lambda: main_thread_update_function(root, q, fig_queue, canvas_widget, progress_label))
209
207
 
210
- return root, vars_dict
208
+ parent_frame.after(100, lambda: main_thread_update_function(parent_frame, q, fig_queue, canvas_widget, progress_label))
209
+
210
+ return parent_frame, vars_dict
211
211
 
212
212
  def gui_mask():
213
- global vars_dict, root
214
- root, vars_dict = initiate_mask_root(1000, 1500)
215
-
213
+ root = tk.Tk()
214
+ root.geometry("1000x800")
215
+ root.title("SpaCer: generate masks")
216
+ initiate_mask_root(root, 1000, 800)
217
+ create_menu_bar(root)
216
218
  root.mainloop()
217
-
219
+
218
220
  if __name__ == "__main__":
219
- gui_mask()
221
+ gui_mask()
222
+
spacr/gui_measure_app.py CHANGED
@@ -1,4 +1,4 @@
1
- import sys, traceback, matplotlib, ctypes, csv
1
+ import sys, traceback, matplotlib, ctypes
2
2
  import tkinter as tk
3
3
  from tkinter import ttk, scrolledtext
4
4
  from matplotlib.figure import Figure
@@ -7,7 +7,7 @@ import matplotlib.pyplot as plt
7
7
  matplotlib.use('Agg') # Use the non-GUI Agg backend
8
8
  from multiprocessing import Process, Queue, Value
9
9
  from ttkthemes import ThemedTk
10
- from tkinter import filedialog, StringVar, BooleanVar, IntVar, DoubleVar, Tk
10
+ from tkinter import filedialog
11
11
 
12
12
  try:
13
13
  ctypes.windll.shcore.SetProcessDpiAwareness(True)
@@ -15,11 +15,41 @@ except AttributeError:
15
15
  pass
16
16
 
17
17
  from .logger import log_function_call
18
- from .gui_utils import ScrollableFrame, StdoutRedirector, process_stdout_stderr, set_dark_style, set_default_font, generate_fields, create_dark_mode, main_thread_update_function
19
- from .gui_utils import measure_variables, measure_crop_wrapper, clear_canvas, safe_literal_eval, check_measure_gui_settings, read_settings_from_csv, update_settings_from_csv
18
+ from .gui_utils import ScrollableFrame, StdoutRedirector, CustomButton, ToggleSwitch
19
+ from .gui_utils import process_stdout_stderr, set_dark_style, set_default_font, generate_fields, main_thread_update_function, create_menu_bar
20
+ from .gui_utils import measure_variables, measure_crop_wrapper, clear_canvas, check_measure_gui_settings, read_settings_from_csv, update_settings_from_csv, style_text_boxes
20
21
 
21
22
  thread_control = {"run_thread": None, "stop_requested": False}
22
23
 
24
+ def toggle_test_mode():
25
+ global vars_dict
26
+ current_state = vars_dict['test_mode'][2].get()
27
+ new_state = not current_state
28
+ vars_dict['test_mode'][2].set(new_state)
29
+ if new_state:
30
+ test_mode_button.config(bg="blue")
31
+ else:
32
+ test_mode_button.config(bg="gray")
33
+
34
+ def toggle_advanced_settings():
35
+ global vars_dict
36
+
37
+ timelapse_settings = ['timelapse', 'timelapse_objects']
38
+ misc_settings = ['representative_images', 'plot', 'plot_filtration', 'include_uninfected', 'dialate_pngs', 'dialate_png_ratios']
39
+ opperational_settings = ['max_workers','experiment','cells','cell_loc','pathogens','pathogen_loc','treatments','treatment_loc','channel_of_interest','compartments','measurement','nr_imgs', 'um_per_pixel']
40
+
41
+ advanced_settings = timelapse_settings+misc_settings+opperational_settings
42
+
43
+ # Toggle visibility of advanced settings
44
+ for setting in advanced_settings:
45
+ label, widget, var = vars_dict[setting]
46
+ if advanced_var.get() is False:
47
+ label.grid_remove() # Hide the label
48
+ widget.grid_remove() # Hide the widget
49
+ else:
50
+ label.grid() # Show the label
51
+ widget.grid() # Show the widget
52
+
23
53
  @log_function_call
24
54
  def run_measure_gui(q, fig_queue, stop_requested):
25
55
  global vars_dict
@@ -27,9 +57,6 @@ def run_measure_gui(q, fig_queue, stop_requested):
27
57
  try:
28
58
  print('hello')
29
59
  settings = check_measure_gui_settings(vars_dict)
30
- #for key in settings:
31
- # value = settings[key]
32
- # print(key, value, type(value))
33
60
  measure_crop_wrapper(settings=settings, q=q, fig_queue=fig_queue)
34
61
  except Exception as e:
35
62
  q.put(f"Error during processing: {e}")
@@ -71,28 +98,17 @@ def import_settings(scrollable_frame):
71
98
  vars_dict = generate_fields(new_settings, scrollable_frame)
72
99
 
73
100
  @log_function_call
74
- def initiate_measure_root(width, height):
75
- global root, vars_dict, q, canvas, fig_queue, canvas_widget, thread_control, variables
101
+ def initiate_measure_root(parent_frame, width, height):
102
+ global vars_dict, q, canvas, fig_queue, canvas_widget, thread_control, variables, advanced_var, scrollable_frame
76
103
 
77
- theme = 'breeze'
78
-
79
- if theme in ['clam']:
80
- root = tk.Tk()
81
- style = ttk.Style(root)
82
- style.theme_use(theme) #plastik, clearlooks, elegance, default was clam #alt, breeze, arc
83
- set_dark_style(style)
84
-
85
- elif theme in ['breeze']:
86
- root = ThemedTk(theme="breeze")
87
- style = ttk.Style(root)
88
- set_dark_style(style)
89
-
90
- set_default_font(root, font_name="Arial", size=10)
91
- #root.state('zoomed') # For Windows to maximize the window
92
- root.attributes('-fullscreen', True)
93
- root.geometry(f"{width}x{height}")
94
- root.configure(bg='#333333')
95
- root.title("SpaCer: generate masks")
104
+ style = ttk.Style(parent_frame)
105
+ set_dark_style(style)
106
+ style_text_boxes(style)
107
+ set_default_font(parent_frame, font_name="Open Sans", size=8)
108
+
109
+ parent_frame.configure(bg='black')
110
+ parent_frame.grid_rowconfigure(0, weight=1)
111
+ parent_frame.grid_columnconfigure(0, weight=1)
96
112
  fig_queue = Queue()
97
113
 
98
114
  def _process_fig_queue():
@@ -101,27 +117,22 @@ def initiate_measure_root(width, height):
101
117
  while not fig_queue.empty():
102
118
  clear_canvas(canvas)
103
119
  fig = fig_queue.get_nowait()
104
- #set_fig_text_properties(fig, font_size=8)
105
120
  for ax in fig.get_axes():
106
121
  ax.set_xticks([]) # Remove x-axis ticks
107
122
  ax.set_yticks([]) # Remove y-axis ticks
108
123
  ax.xaxis.set_visible(False) # Hide the x-axis
109
124
  ax.yaxis.set_visible(False) # Hide the y-axis
110
- #ax.title.set_fontsize(14)
111
- #disable_interactivity(fig)
112
125
  fig.tight_layout()
113
- fig.set_facecolor('#333333')
126
+ fig.set_facecolor('black')
114
127
  canvas.figure = fig
115
128
  fig_width, fig_height = canvas_widget.winfo_width(), canvas_widget.winfo_height()
116
129
  fig.set_size_inches(fig_width / fig.dpi, fig_height / fig.dpi, forward=True)
117
- canvas.draw_idle()
130
+ canvas.draw_idle()
118
131
  except Exception as e:
119
132
  traceback.print_exc()
120
- #pass
121
133
  finally:
122
134
  canvas_widget.after(100, _process_fig_queue)
123
-
124
- # Process queue for console output
135
+
125
136
  def _process_console_queue():
126
137
  while not q.empty():
127
138
  message = q.get_nowait()
@@ -129,71 +140,83 @@ def initiate_measure_root(width, height):
129
140
  console_output.see(tk.END)
130
141
  console_output.after(100, _process_console_queue)
131
142
 
132
- # Vertical container for settings and console
133
- vertical_container = tk.PanedWindow(root, orient=tk.HORIZONTAL) #VERTICAL
134
- vertical_container.pack(fill=tk.BOTH, expand=True)
135
-
136
- # Scrollable Frame for user settings
137
- scrollable_frame = ScrollableFrame(vertical_container)
138
- vertical_container.add(scrollable_frame, stretch="always")
139
-
140
- # Setup for user input fields (variables)
143
+ vertical_container = tk.PanedWindow(parent_frame, orient=tk.HORIZONTAL)
144
+ vertical_container.grid(row=0, column=0, sticky=tk.NSEW)
145
+ parent_frame.grid_rowconfigure(0, weight=1)
146
+ parent_frame.grid_columnconfigure(0, weight=1)
147
+
148
+ # Settings Section
149
+ settings_frame = tk.Frame(vertical_container, bg='black')
150
+ vertical_container.add(settings_frame, stretch="always")
151
+ settings_label = ttk.Label(settings_frame, text="Settings", background="black", foreground="white")
152
+ settings_label.grid(row=0, column=0, pady=10, padx=10)
153
+ scrollable_frame = ScrollableFrame(settings_frame, width=500)
154
+ scrollable_frame.grid(row=1, column=0, sticky="nsew")
155
+ settings_frame.grid_rowconfigure(1, weight=1)
156
+ settings_frame.grid_columnconfigure(0, weight=1)
157
+
158
+ # Create advanced settings checkbox
159
+ advanced_var = tk.BooleanVar(value=False)
160
+ advanced_Toggle = ToggleSwitch(scrollable_frame.scrollable_frame, text="Advanced Settings", variable=advanced_var, command=toggle_advanced_settings)
161
+ advanced_Toggle.grid(row=48, column=0, pady=10, padx=10)
141
162
  variables = measure_variables()
142
163
  vars_dict = generate_fields(variables, scrollable_frame)
164
+ toggle_advanced_settings()
165
+ vars_dict['Test mode'] = (None, None, tk.BooleanVar(value=False))
143
166
 
144
- # Horizontal container for Matplotlib figure and the vertical pane (for settings and console)
145
- horizontal_container = tk.PanedWindow(vertical_container, orient=tk.VERTICAL) #HORIZONTAL
146
- vertical_container.add(horizontal_container, stretch="always")
147
-
148
- # Matplotlib figure setup
149
- figure = Figure(figsize=(30, 4), dpi=100, facecolor='#333333')
167
+ # Button section
168
+ test_mode_button = CustomButton(scrollable_frame.scrollable_frame, text="Test Mode", command=toggle_test_mode)
169
+ test_mode_button.grid(row=47, column=1, pady=10, padx=10)
170
+ import_btn = CustomButton(scrollable_frame.scrollable_frame, text="Import Settings", command=lambda: import_settings(scrollable_frame))
171
+ import_btn.grid(row=47, column=0, pady=20, padx=20)
172
+ run_button = CustomButton(scrollable_frame.scrollable_frame, text="Run", command=lambda: start_process(q, fig_queue))
173
+ run_button.grid(row=45, column=0, pady=20, padx=20)
174
+ abort_button = CustomButton(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort)
175
+ abort_button.grid(row=45, column=1, pady=20, padx=20)
176
+ progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Processing: 0%", background="black", foreground="white") # Create progress field
177
+ progress_label.grid(row=50, column=0, columnspan=2, sticky="ew", pady=(5, 0), padx=10)
178
+
179
+ # Plot Canvas Section
180
+ plot_frame = tk.PanedWindow(vertical_container, orient=tk.VERTICAL)
181
+ vertical_container.add(plot_frame, stretch="always")
182
+ figure = Figure(figsize=(30, 4), dpi=100, facecolor='black')
150
183
  plot = figure.add_subplot(111)
151
- plot.plot([], []) # This creates an empty plot.
184
+ plot.plot([], [])
152
185
  plot.axis('off')
153
-
154
- # Embedding the Matplotlib figure in the Tkinter window
155
- canvas = FigureCanvasTkAgg(figure, master=horizontal_container)
156
- canvas.get_tk_widget().configure(cursor='arrow', background='#333333', highlightthickness=0)
157
- #canvas.get_tk_widget().configure(cursor='arrow')
186
+ canvas = FigureCanvasTkAgg(figure, master=plot_frame)
187
+ canvas.get_tk_widget().configure(cursor='arrow', background='black', highlightthickness=0)
158
188
  canvas_widget = canvas.get_tk_widget()
159
- horizontal_container.add(canvas_widget, stretch="always")
189
+ plot_frame.add(canvas_widget, stretch="always")
160
190
  canvas.draw()
161
191
  canvas.figure = figure
162
192
 
163
- # Console output setup below the settings
164
- console_output = scrolledtext.ScrolledText(vertical_container, height=10)
165
- vertical_container.add(console_output, stretch="always")
193
+ # Console Section
194
+ console_frame = tk.Frame(vertical_container, bg='black')
195
+ vertical_container.add(console_frame, stretch="always")
196
+ console_label = ttk.Label(console_frame, text="Console", background="black", foreground="white")
197
+ console_label.grid(row=0, column=0, pady=10, padx=10)
198
+ console_output = scrolledtext.ScrolledText(console_frame, height=10, bg='black', fg='white', insertbackground='white')
199
+ console_output.grid(row=1, column=0, sticky="nsew")
200
+ console_frame.grid_rowconfigure(1, weight=1)
201
+ console_frame.grid_columnconfigure(0, weight=1)
166
202
 
167
- # Queue and redirection setup for updating console output safely
168
203
  q = Queue()
169
204
  sys.stdout = StdoutRedirector(console_output)
170
205
  sys.stderr = StdoutRedirector(console_output)
171
206
 
172
- # This is your GUI setup where you create the Run button
173
- run_button = ttk.Button(scrollable_frame.scrollable_frame, text="Run",command=lambda: start_process(q, fig_queue))
174
- run_button.grid(row=40, column=0, pady=10)
175
-
176
- abort_button = ttk.Button(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort)
177
- abort_button.grid(row=40, column=1, pady=10)
178
-
179
- progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Progress: ", background="#333333", foreground="white")
180
- progress_label.grid(row=41, column=0, columnspan=2, sticky="ew", pady=(5, 0))
181
-
182
- # Create the Import Settings button
183
- import_btn = tk.Button(root, text="Import Settings", command=lambda: import_settings(scrollable_frame))
184
- import_btn.pack(pady=20)
185
-
186
207
  _process_console_queue()
187
208
  _process_fig_queue()
188
- create_dark_mode(root, style, console_output)
189
209
 
190
- #root.after(100, lambda: main_thread_update_function(root, q, fig_queue, canvas_widget, progress_label))
210
+ parent_frame.after(100, lambda: main_thread_update_function(parent_frame, q, fig_queue, canvas_widget, progress_label))
191
211
 
192
- return root, vars_dict
212
+ return parent_frame, vars_dict
193
213
 
194
214
  def gui_measure():
195
- global vars_dict, root
196
- root, vars_dict = initiate_measure_root(1000, 1500)
215
+ root = tk.Tk()
216
+ root.geometry("1000x800")
217
+ root.title("SpaCer: generate masks")
218
+ initiate_measure_root(root, 1000, 800)
219
+ create_menu_bar(root)
197
220
  root.mainloop()
198
221
 
199
222
  if __name__ == "__main__":