From 93db0c21efe9d7170a82af2cb0621caa3cd6cb09 Mon Sep 17 00:00:00 2001
From: wyzula-jan <133381102+wyzula-jan@users.noreply.github.com>
Date: Thu, 26 Oct 2023 15:36:03 +0200
Subject: [PATCH] refactor: config_dialog.py clean up
---
bec_widgets/examples/extreme/extreme.py | 6 +-
.../examples/modular_app/modular_app.py | 4 +-
bec_widgets/widgets/monitor/config_dialog.py | 104 ++++++++----------
bec_widgets/widgets/monitor/config_dialog.ui | 23 +---
4 files changed, 55 insertions(+), 82 deletions(-)
diff --git a/bec_widgets/examples/extreme/extreme.py b/bec_widgets/examples/extreme/extreme.py
index c31a20fc..71fdc244 100644
--- a/bec_widgets/examples/extreme/extreme.py
+++ b/bec_widgets/examples/extreme/extreme.py
@@ -435,7 +435,9 @@ class PlotApp(QWidget):
curve.setData(data_x, data_y)
@pyqtSlot(dict, dict)
- def on_scan_segment(self, msg, metadata) -> None:
+ def on_scan_segment(
+ self, msg, metadata
+ ) -> None: # TODO the logic should be separated from GUI operation
"""
Handle new scan segments and saves data to a dictionary. Linked through bec_dispatcher.
@@ -566,7 +568,7 @@ class PlotApp(QWidget):
except Exception as e:
print(f"An error occurred while saving the settings to {file_path}: {e}")
- def load_settings_from_yaml(self) -> dict:
+ def load_settings_from_yaml(self) -> dict: # TODO can be replace by the qt_utils function
"""Load settings from a .yaml file using a file dialog and update the current settings."""
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
diff --git a/bec_widgets/examples/modular_app/modular_app.py b/bec_widgets/examples/modular_app/modular_app.py
index 637b978c..ec4ff48e 100644
--- a/bec_widgets/examples/modular_app/modular_app.py
+++ b/bec_widgets/examples/modular_app/modular_app.py
@@ -150,7 +150,7 @@ config_scan_mode = {
"label": "Multi",
"signals": [
{"name": "gauss_bpm", "entry": "gauss_bpm"},
- {"name": "samx", "entry": ["samx", "samx_setpoint"]},
+ {"name": "samx", "entry": "samx"},
],
},
},
@@ -161,7 +161,7 @@ config_scan_mode = {
"label": "Multi",
"signals": [
{"name": "gauss_bpm", "entry": "gauss_bpm"},
- {"name": "samx", "entry": ["samx", "samx_setpoint"]},
+ {"name": "samx", "entry": "samx"},
],
},
},
diff --git a/bec_widgets/widgets/monitor/config_dialog.py b/bec_widgets/widgets/monitor/config_dialog.py
index 30c481c5..f053db1e 100644
--- a/bec_widgets/widgets/monitor/config_dialog.py
+++ b/bec_widgets/widgets/monitor/config_dialog.py
@@ -13,7 +13,6 @@ from PyQt5.QtWidgets import (
)
from bec_widgets.qt_utils.yaml_dialog import load_yaml, save_yaml
-from bec_widgets.qt_utils.widget_hierarchy import print_widget_hierarchy, export_config_to_dict
current_path = os.path.dirname(__file__)
Ui_Form, BaseClass = uic.loadUiType(os.path.join(current_path, "config_dialog.ui"))
@@ -164,14 +163,6 @@ class ConfigDialog(QWidget, Ui_Form):
)
)
- # Debug buttons
- self.pushButton_hirarchy.clicked.connect(self.debug_hierarchy)
-
- # Test button configuration to load configs from dict
- self.pushButton_def.clicked.connect(lambda: self.load_config(config=config_default))
- self.pushButton_scan.clicked.connect(lambda: self.load_config(config=config_scan))
- # self.pushButton_hierarchy.clicked.connect(lambda: print_widget_hierarchy(self))
-
# Load/save yaml file buttons
self.pushButton_import.clicked.connect(self.load_config_from_yaml)
self.pushButton_export.clicked.connect(self.save_config_to_yaml)
@@ -182,24 +173,21 @@ class ConfigDialog(QWidget, Ui_Form):
# Make scan tabs closable
self.tabWidget_scan_types.tabCloseRequested.connect(self.handle_tab_close_request)
- # Default configuration
- # Init functions to make a default dialog #TODO this is useful, but has to be made better
+ # Init functions to make a default dialog
if default_config is None:
self._init_default()
- # self.load_config()
-
- def debug_hierarchy(self):
- self.hierarchy_dict = export_config_to_dict(self, grab_values=True, print_hierarchy=True)
- print(self.hierarchy_dict)
+ else:
+ self.load_config(default_config)
def _init_default(self):
- if self.comboBox_scanTypes.currentText() == "Disabled":
+ """Init default dialog"""
+
+ if self.comboBox_scanTypes.currentText() == "Disabled": # Default mode
self.add_new_scan(self.tabWidget_scan_types, "Default")
self.add_new_plot(self.tabWidget_scan_types.widget(0))
self.pushButton_new_scan_type.setEnabled(False)
self.lineEdit_scan_type.setEnabled(False)
- else:
- print("scan mode from _init")
+ else: # Scan mode with clear tab
self.pushButton_new_scan_type.setEnabled(True)
self.lineEdit_scan_type.setEnabled(True)
self.tabWidget_scan_types.clear()
@@ -214,16 +202,18 @@ class ConfigDialog(QWidget, Ui_Form):
parent_tab(QTabWidget): Parent tab widget, where to add scan tab
scan_name(str): Scan name
closable(bool): If True, the scan tab will be closable
+
Returns:
scan_tab(QWidget): Scan tab widget
"""
+
# Create a new scan tab
scan_tab = QWidget()
scan_tab_layout = QVBoxLayout(scan_tab)
# Set a tab widget for plots
tabWidget_plots = QTabWidget()
- tabWidget_plots.setObjectName("tabWidget_plots")
+ tabWidget_plots.setObjectName("tabWidget_plots") # TODO decide if needed to give a name
tabWidget_plots.setTabsClosable(True)
tabWidget_plots.tabCloseRequested.connect(self.handle_tab_close_request)
scan_tab_layout.addWidget(tabWidget_plots)
@@ -231,23 +221,23 @@ class ConfigDialog(QWidget, Ui_Form):
# Add scan tab
parent_tab.addTab(scan_tab, scan_name)
- # Optionally, connect the tabCloseRequested signal to a slot to handle the tab close request
+ # Make tabs closable
if closable:
parent_tab.setTabsClosable(closable)
- # Add first plot #TODO decide if useful for both modes
- # self.add_new_plot(scan_tab)
+
return scan_tab
def add_new_plot(self, scan_tab: QWidget) -> QWidget:
"""
Add a new plot tab to the scan tab
+
Args:
scan_tab (QWidget): Scan tab widget
Returns:
plot_tab (QWidget): Plot tab
-
"""
+
# Create a new plot tab from .ui template
plot_tab = QWidget()
plot_tab_ui = Tab_Ui_Form()
@@ -255,7 +245,9 @@ class ConfigDialog(QWidget, Ui_Form):
plot_tab.ui = plot_tab_ui
# Add plot to current scan tab
- tabWidget_plots = scan_tab.findChild(QTabWidget, "tabWidget_plots")
+ tabWidget_plots = scan_tab.findChild(
+ QTabWidget, "tabWidget_plots"
+ ) # TODO decide if putting name is needed
plot_name = f"Plot {tabWidget_plots.count() + 1}"
tabWidget_plots.addTab(plot_tab, plot_name)
@@ -281,9 +273,11 @@ class ConfigDialog(QWidget, Ui_Form):
def add_new_signal(self, table: QTableWidget) -> None:
"""
Add a new signal to the table
+
Args:
table(QTableWidget): Table widget
"""
+
row_position = table.rowCount()
table.insertRow(row_position)
table.setItem(row_position, 0, QTableWidgetItem(""))
@@ -296,17 +290,21 @@ class ConfigDialog(QWidget, Ui_Form):
Args:
index(int): Index of the tab to be closed
"""
+
parent_tab = self.sender()
- parent_tab.removeTab(index)
+ if parent_tab.count() > 1: # ensure there is at least one tab
+ parent_tab.removeTab(index)
def generate_empty_scan_tab(self, parent_tab: QTabWidget, scan_name: str):
"""
Generate an empty scan tab
+
Args:
parent_tab (QTabWidget): Parent tab widget where to add the scan tab
scan_name(str): name of the scan tab
"""
- scan_tab = self.add_new_scan(parent_tab, scan_name, True)
+
+ scan_tab = self.add_new_scan(parent_tab, scan_name, closable=True)
self.add_new_plot(scan_tab)
def get_plot_config(self, plot_tab: QWidget) -> dict:
@@ -346,6 +344,7 @@ class ConfigDialog(QWidget, Ui_Form):
"signals": signals,
},
}
+
return plot_data
def apply_config(self) -> dict:
@@ -353,9 +352,10 @@ class ConfigDialog(QWidget, Ui_Form):
Apply configuration from the whole configuration window
Returns:
- dict: Configuration
+ dict: Current configuration
"""
+
# General settings
config = {
"plot_settings": {
@@ -369,13 +369,8 @@ class ConfigDialog(QWidget, Ui_Form):
# Iterate through the plot tabs - Device monitor mode
if config["plot_settings"]["scan_types"] == False:
- plot_tab = self.tabWidget_scan_types.widget(0).findChild(
- QTabWidget
- ) # , "tabWidget_plots") #TODO bug was here?
- print(f"number of tabs: {plot_tab.count()}")
+ plot_tab = self.tabWidget_scan_types.widget(0).findChild(QTabWidget)
for index in range(plot_tab.count()):
- print(f"plot MODE tab index: {index}")
- # export_config_to_dict(plot_tab.widget(index), print_hierarchy=True, grab_values=True)
plot_data = self.get_plot_config(plot_tab.widget(index))
config["plot_data"].append(plot_data)
@@ -383,54 +378,50 @@ class ConfigDialog(QWidget, Ui_Form):
elif config["plot_settings"]["scan_types"] == True:
# Iterate through the scan tabs
for index in range(self.tabWidget_scan_types.count()):
- print(f"scan tab index: {index}")
scan_tab = self.tabWidget_scan_types.widget(index)
scan_name = self.tabWidget_scan_types.tabText(index)
- plot_tab = scan_tab.findChild(QTabWidget) # TODO here bug?
+ plot_tab = scan_tab.findChild(QTabWidget)
config["plot_data"][scan_name] = []
+ # Iterate through the plot tabs
for index in range(plot_tab.count()):
- print(f"plot tab index: {index}")
plot_data = self.get_plot_config(plot_tab.widget(index))
config["plot_data"][scan_name].append(plot_data)
- print(f"applied config: {config})")
return config
def load_config(self, config: dict) -> None:
+ """
+ Load configuration to the configuration window
+
+ Args:
+ config(dict): Configuration to be loaded
+ """
+
# Plot setting General box
plot_settings = config.get("plot_settings", {})
- # TODO implement more robust logic for color apply/select
- self.comboBox_appearance.setCurrentText(plot_settings.get("background_color", ""))
+ self.comboBox_appearance.setCurrentText(plot_settings.get("background_color", "black"))
self.spinBox_n_column.setValue(plot_settings.get("num_columns", 1))
- self.comboBox_colormap.setCurrentText(plot_settings.get("colormap", ""))
+ self.comboBox_colormap.setCurrentText(plot_settings.get("colormap", "magma"))
self.comboBox_scanTypes.setCurrentText(
"Enabled" if plot_settings.get("scan_types", False) else "Disabled"
)
# Clear exiting scan tabs
- self.tabWidget_scan_types.clear() # TODO can cause var leak?
+ self.tabWidget_scan_types.clear()
# Get what mode is active - scan vs default device monitor
- mode = plot_settings.get("scan_types", False)
+ scan_mode = plot_settings.get("scan_types", False)
- print(f"scan mode:{mode}")
-
- # default mode
- if mode is False:
+ if scan_mode is False: # default mode:
plot_data = config.get("plot_data", [])
self.add_new_scan(self.tabWidget_scan_types, "Default")
- for plot_config in plot_data: # TODO iterate through all plots
- print(f"plot_config: {plot_config}")
-
- # Create plot tab for each plot and populate GUI
+ for plot_config in plot_data: # Create plot tab for each plot and populate GUI
plot = self.add_new_plot(self.tabWidget_scan_types.widget(0))
self.load_plot_setting(plot, plot_config)
- elif mode is True:
+ elif scan_mode is True: # scan mode
plot_data = config.get("plot_data", {})
for scan_name, scan_config in plot_data.items():
- print(f"scan name: {scan_name}")
- print(f"scan config: {scan_config}")
scan_tab = self.add_new_scan(self.tabWidget_scan_types, scan_name)
for plot_config in scan_config:
plot = self.add_new_plot(scan_tab)
@@ -439,6 +430,7 @@ class ConfigDialog(QWidget, Ui_Form):
def load_plot_setting(self, plot: QWidget, plot_config: dict) -> None:
"""
Load plot setting from config
+
Args:
plot (QWidget): plot tab widget
plot_config (dict): config for single plot tab
@@ -480,7 +472,6 @@ class ConfigDialog(QWidget, Ui_Form):
Save configuration to yaml file
"""
config = self.apply_config()
- print(f"confgi to save:{config}")
save_yaml(self, config)
@staticmethod
@@ -496,7 +487,8 @@ class ConfigDialog(QWidget, Ui_Form):
return "" if line_edit is None else line_edit.text()
def apply_and_close(self):
- self.apply_config()
+ new_config = self.apply_config()
+ self.config_updated.emit(new_config)
self.close()
diff --git a/bec_widgets/widgets/monitor/config_dialog.ui b/bec_widgets/widgets/monitor/config_dialog.ui
index 71470d50..09e403d6 100644
--- a/bec_widgets/widgets/monitor/config_dialog.ui
+++ b/bec_widgets/widgets/monitor/config_dialog.ui
@@ -6,7 +6,7 @@
0
0
- 585
+ 597
769
@@ -141,27 +141,6 @@
Configuration
- -
-
-
- Hiearchy
-
-
-
- -
-
-
- ImpDef
-
-
-
- -
-
-
- ImpScan
-
-
-
-