mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-14 11:41:49 +02:00
refactor: qt_utils/hierarchy function refactored to use widget handler allowing to add more widget support in the future
This commit is contained in:
@ -1,39 +1,134 @@
|
|||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QTabWidget,
|
QApplication,
|
||||||
|
QWidget,
|
||||||
QLineEdit,
|
QLineEdit,
|
||||||
QComboBox,
|
QComboBox,
|
||||||
QTableWidget,
|
QTableWidget,
|
||||||
QSpinBox,
|
QSpinBox,
|
||||||
QDoubleSpinBox,
|
QDoubleSpinBox,
|
||||||
QTableWidgetItem,
|
QTableWidgetItem,
|
||||||
|
QVBoxLayout,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def print_widget_hierarchy(widget, indent: int = 0):
|
class WidgetHandler:
|
||||||
|
@staticmethod
|
||||||
|
def get_value(widget):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def set_value(widget, value):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
class LineEditHandler(WidgetHandler):
|
||||||
|
@staticmethod
|
||||||
|
def get_value(widget):
|
||||||
|
return widget.text()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def set_value(widget, value):
|
||||||
|
widget.setText(value)
|
||||||
|
|
||||||
|
|
||||||
|
class ComboBoxHandler(WidgetHandler):
|
||||||
|
@staticmethod
|
||||||
|
def get_value(widget):
|
||||||
|
return widget.currentIndex()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def set_value(widget, value):
|
||||||
|
widget.setCurrentIndex(value)
|
||||||
|
|
||||||
|
|
||||||
|
class TableWidgetHandler(WidgetHandler):
|
||||||
|
@staticmethod
|
||||||
|
def get_value(widget):
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
widget.item(row, col).text() if widget.item(row, col) else ""
|
||||||
|
for col in range(widget.columnCount())
|
||||||
|
]
|
||||||
|
for row in range(widget.rowCount())
|
||||||
|
]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def set_value(widget, value):
|
||||||
|
for row, row_values in enumerate(value):
|
||||||
|
for col, cell_value in enumerate(row_values):
|
||||||
|
item = QTableWidgetItem(str(cell_value))
|
||||||
|
widget.setItem(row, col, item)
|
||||||
|
|
||||||
|
|
||||||
|
class SpinBoxHandler(WidgetHandler):
|
||||||
|
@staticmethod
|
||||||
|
def get_value(widget):
|
||||||
|
return widget.value()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def set_value(widget, value):
|
||||||
|
widget.setValue(value)
|
||||||
|
|
||||||
|
|
||||||
|
HANDLERS = {
|
||||||
|
QLineEdit: LineEditHandler,
|
||||||
|
QComboBox: ComboBoxHandler,
|
||||||
|
QTableWidget: TableWidgetHandler,
|
||||||
|
QSpinBox: SpinBoxHandler,
|
||||||
|
QDoubleSpinBox: SpinBoxHandler,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_value(widget):
|
||||||
|
handler_class = HANDLERS.get(type(widget))
|
||||||
|
if handler_class:
|
||||||
|
return handler_class.get_value(widget)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def set_value(widget, value):
|
||||||
|
handler_class = HANDLERS.get(type(widget))
|
||||||
|
if handler_class:
|
||||||
|
handler_class.set_value(widget, value)
|
||||||
|
|
||||||
|
|
||||||
|
def print_widget_hierarchy(
|
||||||
|
widget, indent: int = 0, grab_values: bool = False, prefix: str = ""
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Print the widget hierarchy to the console.
|
Print the widget hierarchy to the console.
|
||||||
Args:
|
Args:
|
||||||
widget: Widget to print the hierarchy of.
|
widget: Widget to print the hierarchy of.
|
||||||
indent(int): Level of indentation.
|
indent(int, optional): Level of indentation.
|
||||||
|
grab_values(bool,optional): Whether to grab the values of the widgets.
|
||||||
|
prefix(stc,optional): Custom string prefix for indentation.
|
||||||
"""
|
"""
|
||||||
print(" " * indent + f"{widget.__class__.__name__} ({widget.objectName()})")
|
widget_info = f"{widget.__class__.__name__} ({widget.objectName()})"
|
||||||
for child in widget.children():
|
if grab_values:
|
||||||
print_widget_hierarchy(child, indent + 1)
|
value = get_value(widget)
|
||||||
|
value_str = f" [value: {value}]" if value is not None else ""
|
||||||
|
widget_info += value_str
|
||||||
|
|
||||||
|
print(prefix + widget_info)
|
||||||
|
|
||||||
|
children = widget.children()
|
||||||
|
for child in children:
|
||||||
|
child_prefix = prefix + " "
|
||||||
|
arrow = "├─ " if child != children[-1] else "└─ "
|
||||||
|
print_widget_hierarchy(child, indent + 1, grab_values, prefix=child_prefix + arrow)
|
||||||
|
|
||||||
|
|
||||||
def export_config_to_dict(
|
def export_config_to_dict(
|
||||||
widget, config: dict = None, indent: int = 0, grab_values=False, print_hierarchy=False
|
widget, config=None, indent=0, grab_values: bool = False, print_hierarchy: bool = False
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""
|
"""
|
||||||
Export the widget hierarchy to a dictionary.
|
Export the widget hierarchy to a dictionary.
|
||||||
Args:
|
Args:
|
||||||
widget: widget to export the hierarchy of.
|
widget: Widget to print the hierarchy of.
|
||||||
config(dict,optional): Dictionary to export the hierarchy to.
|
config(dict,optional): Dictionary to export the hierarchy to.
|
||||||
indent(int): Level of indentation.
|
indent(int,optional): Level of indentation.
|
||||||
grab_values(bool): Whether to grab the values of the widgets.
|
grab_values(bool,optional): Whether to grab the values of the widgets.
|
||||||
print_hierarchy(bool): Whether to print the hierarchy to the console.
|
print_hierarchy(bool,optional): Whether to print the hierarchy to the console.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
config(dict): Dictionary containing the widget hierarchy.
|
config(dict): Dictionary containing the widget hierarchy.
|
||||||
"""
|
"""
|
||||||
@ -41,79 +136,79 @@ def export_config_to_dict(
|
|||||||
config = {}
|
config = {}
|
||||||
widget_info = f"{widget.__class__.__name__} ({widget.objectName()})"
|
widget_info = f"{widget.__class__.__name__} ({widget.objectName()})"
|
||||||
config[widget_info] = {}
|
config[widget_info] = {}
|
||||||
if isinstance(widget, QTabWidget):
|
|
||||||
config[widget_info]["currentIndex"] = widget.currentIndex()
|
|
||||||
if grab_values:
|
if grab_values:
|
||||||
if isinstance(widget, QLineEdit):
|
value = get_value(widget)
|
||||||
config[widget_info]["text"] = widget.text()
|
if value is not None:
|
||||||
elif isinstance(widget, QComboBox):
|
config[widget_info]["value"] = value
|
||||||
config[widget_info]["currentIndex"] = widget.currentIndex()
|
|
||||||
elif isinstance(widget, QTableWidget):
|
|
||||||
config[widget_info]["tableData"] = [
|
|
||||||
[
|
|
||||||
widget.item(row, col).text() if widget.item(row, col) else ""
|
|
||||||
for col in range(widget.columnCount())
|
|
||||||
]
|
|
||||||
for row in range(widget.rowCount())
|
|
||||||
]
|
|
||||||
elif isinstance(widget, QSpinBox):
|
|
||||||
config[widget_info]["value"] = widget.value()
|
|
||||||
elif isinstance(widget, QDoubleSpinBox):
|
|
||||||
config[widget_info]["value"] = widget.value()
|
|
||||||
|
|
||||||
if print_hierarchy:
|
if print_hierarchy:
|
||||||
extra_info = ""
|
print_widget_hierarchy(widget, indent, grab_values)
|
||||||
if grab_values:
|
|
||||||
if isinstance(widget, QLineEdit):
|
|
||||||
extra_info = f" [text: {widget.text()}]"
|
|
||||||
elif isinstance(widget, QComboBox):
|
|
||||||
extra_info = f" [currentIndex: {widget.currentIndex()}]"
|
|
||||||
elif isinstance(widget, QTableWidget):
|
|
||||||
extra_info = f" [tableData: {config[widget_info]['tableData']}]"
|
|
||||||
elif isinstance(widget, QSpinBox):
|
|
||||||
extra_info = f" [value: {widget.value()}]"
|
|
||||||
elif isinstance(widget, QDoubleSpinBox):
|
|
||||||
extra_info = f" [value: {widget.value()}]"
|
|
||||||
print(" " * indent + f"{widget_info}{extra_info}")
|
|
||||||
|
|
||||||
for child in widget.children():
|
for child in widget.children():
|
||||||
export_config_to_dict(
|
export_config_to_dict(child, config, indent + 1, grab_values, print_hierarchy)
|
||||||
child,
|
|
||||||
config=config,
|
|
||||||
indent=indent + 1,
|
|
||||||
grab_values=grab_values,
|
|
||||||
print_hierarchy=print_hierarchy,
|
|
||||||
)
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
def import_config_from_dict(widget, config, grab_values=False): # TODO decide if useful
|
def import_config_from_dict(widget, config: dict, set_values: bool = False) -> None:
|
||||||
|
"""
|
||||||
|
Import the widget hierarchy from a dictionary.
|
||||||
|
Args:
|
||||||
|
widget: Widget to import the hierarchy to.
|
||||||
|
config:
|
||||||
|
set_values:
|
||||||
|
"""
|
||||||
widget_name = f"{widget.__class__.__name__} ({widget.objectName()})"
|
widget_name = f"{widget.__class__.__name__} ({widget.objectName()})"
|
||||||
widget_config = config.get(widget_name, {})
|
widget_config = config.get(widget_name, {})
|
||||||
for child in widget.children():
|
for child in widget.children():
|
||||||
child_name = f"{child.__class__.__name__} ({child.objectName()})"
|
child_name = f"{child.__class__.__name__} ({child.objectName()})"
|
||||||
child_config = widget_config.get(child_name)
|
child_config = widget_config.get(child_name)
|
||||||
if child_config is not None:
|
if child_config is not None:
|
||||||
if isinstance(child, QTabWidget):
|
value = child_config.get("value")
|
||||||
child.setCurrentIndex(child_config.get("currentIndex", 0))
|
if set_values and value is not None:
|
||||||
for i in range(child.count()):
|
set_value(child, value)
|
||||||
tab = child.widget(i)
|
import_config_from_dict(child, widget_config, set_values)
|
||||||
import_config_from_dict(tab, widget_config, grab_values)
|
|
||||||
else:
|
|
||||||
import_config_from_dict(child, widget_config, grab_values)
|
|
||||||
|
|
||||||
if grab_values:
|
|
||||||
if isinstance(child, QLineEdit):
|
# Example application to demonstrate the usage of the functions
|
||||||
child.setText(child_config.get("text", ""))
|
if __name__ == "__main__":
|
||||||
elif isinstance(child, QComboBox):
|
app = QApplication([])
|
||||||
child.setCurrentIndex(child_config.get("currentIndex", 0))
|
|
||||||
elif isinstance(child, QTableWidget):
|
# Create a simple widget hierarchy for demonstration purposes
|
||||||
table_values = child_config.get("tableValues", [])
|
main_widget = QWidget()
|
||||||
for row, row_values in enumerate(table_values):
|
layout = QVBoxLayout(main_widget)
|
||||||
for col, value in enumerate(row_values):
|
line_edit = QLineEdit(main_widget)
|
||||||
item = QTableWidgetItem(str(value))
|
combo_box = QComboBox(main_widget)
|
||||||
child.setItem(row, col, item)
|
table_widget = QTableWidget(2, 2, main_widget)
|
||||||
elif isinstance(child, QSpinBox):
|
spin_box = QSpinBox(main_widget)
|
||||||
child.setValue(child_config.get("value", 0))
|
layout.addWidget(line_edit)
|
||||||
elif isinstance(child, QDoubleSpinBox):
|
layout.addWidget(combo_box)
|
||||||
child.setValue(child_config.get("value", 0.0))
|
layout.addWidget(table_widget)
|
||||||
|
layout.addWidget(spin_box)
|
||||||
|
|
||||||
|
# Add text items to the combo box
|
||||||
|
combo_box.addItems(["Option 1", "Option 2", "Option 3"])
|
||||||
|
|
||||||
|
main_widget.show()
|
||||||
|
|
||||||
|
# Hierarchy of original widget
|
||||||
|
print(30 * "#")
|
||||||
|
print(f"Widget hierarchy for {main_widget.objectName()}:")
|
||||||
|
print(30 * "#")
|
||||||
|
config_dict = export_config_to_dict(main_widget, grab_values=True, print_hierarchy=True)
|
||||||
|
print(30 * "#")
|
||||||
|
print(f"Config dict: {config_dict}")
|
||||||
|
|
||||||
|
# Hierarchy of new widget and set values
|
||||||
|
new_config_dict = {
|
||||||
|
"QWidget ()": {
|
||||||
|
"QLineEdit ()": {"value": "New Text"},
|
||||||
|
"QComboBox ()": {"value": 1},
|
||||||
|
"QTableWidget ()": {"value": [["a", "b"], ["c", "d"]]},
|
||||||
|
"QSpinBox ()": {"value": 10},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
import_config_from_dict(main_widget, new_config_dict, set_values=True)
|
||||||
|
print(30 * "#")
|
||||||
|
config_dict_new = export_config_to_dict(main_widget, grab_values=True, print_hierarchy=True)
|
||||||
|
print(30 * "#")
|
||||||
|
print(f"Config dict new: {config_dict_new}")
|
||||||
|
|
||||||
|
app.exec()
|
||||||
|
Reference in New Issue
Block a user