mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-14 11:41:49 +02:00
refactor: scan_control.py kwargs and args layouts changed to QGridLayouts
This commit is contained in:
@ -14,6 +14,7 @@ from PyQt5.QtWidgets import (
|
|||||||
QFrame,
|
QFrame,
|
||||||
QHBoxLayout,
|
QHBoxLayout,
|
||||||
QLayout,
|
QLayout,
|
||||||
|
QGridLayout,
|
||||||
)
|
)
|
||||||
|
|
||||||
from bec_lib.core import MessageEndpoints
|
from bec_lib.core import MessageEndpoints
|
||||||
@ -64,7 +65,7 @@ class ScanControl(QWidget):
|
|||||||
self.verticalLayout.addWidget(self.scan_control_group)
|
self.verticalLayout.addWidget(self.scan_control_group)
|
||||||
|
|
||||||
# Kwargs layout
|
# Kwargs layout
|
||||||
self.kwargs_layout = QVBoxLayout()
|
self.kwargs_layout = QGridLayout()
|
||||||
self.scan_control_layout.addLayout(self.kwargs_layout)
|
self.scan_control_layout.addLayout(self.kwargs_layout)
|
||||||
|
|
||||||
# 1st Separator
|
# 1st Separator
|
||||||
@ -84,7 +85,7 @@ class ScanControl(QWidget):
|
|||||||
self.add_horizontal_separator(self.scan_control_layout)
|
self.add_horizontal_separator(self.scan_control_layout)
|
||||||
|
|
||||||
# Args layout
|
# Args layout
|
||||||
self.args_layout = QVBoxLayout()
|
self.args_layout = QGridLayout()
|
||||||
self.scan_control_layout.addLayout(self.args_layout)
|
self.scan_control_layout.addLayout(self.args_layout)
|
||||||
|
|
||||||
# Initialize scan selection
|
# Initialize scan selection
|
||||||
@ -132,19 +133,18 @@ class ScanControl(QWidget):
|
|||||||
self.args_layout, self.arg_input.items()
|
self.args_layout, self.arg_input.items()
|
||||||
) # Add first row of widgets
|
) # Add first row of widgets
|
||||||
|
|
||||||
def add_labels(self, labels: list, layout) -> None:
|
def add_labels(self, labels: list, grid_layout: QGridLayout) -> None:
|
||||||
"""
|
"""
|
||||||
Adds labels to the given layout in QHBox layout
|
Adds labels to the given grid layout as a separate row.
|
||||||
Args:
|
Args:
|
||||||
labels(list): List of labels to add
|
labels (list): List of label names to add.
|
||||||
layout: Layout to add the labels to
|
grid_layout (QGridLayout): The grid layout to which labels will be added.
|
||||||
"""
|
"""
|
||||||
label_layout = QHBoxLayout()
|
row_index = grid_layout.rowCount() # Get the next available row
|
||||||
for col_idx, param in enumerate(labels):
|
for column_index, label_name in enumerate(labels):
|
||||||
label = QLabel(param.capitalize(), self.scan_control_group)
|
label = QLabel(label_name.capitalize(), self.scan_control_group)
|
||||||
label_layout.addWidget(label)
|
# Add the label to the grid layout at the calculated row and current column
|
||||||
|
grid_layout.addWidget(label, row_index, column_index)
|
||||||
layout.addLayout(label_layout)
|
|
||||||
|
|
||||||
def generate_kwargs_input_fields(self, scan_info: dict) -> None:
|
def generate_kwargs_input_fields(self, scan_info: dict) -> None:
|
||||||
"""
|
"""
|
||||||
@ -168,24 +168,25 @@ class ScanControl(QWidget):
|
|||||||
self.add_widgets_row_to_layout(self.kwargs_layout, kwargs, signature)
|
self.add_widgets_row_to_layout(self.kwargs_layout, kwargs, signature)
|
||||||
|
|
||||||
def add_widgets_row_to_layout(
|
def add_widgets_row_to_layout(
|
||||||
self, layout: QLayout, items: list, signature: dict = None
|
self, grid_layout: QGridLayout, items: list, signature: dict = None
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Adds widgets to the given layout as a row in QHBox layout
|
Adds widgets to the given grid layout as a row.
|
||||||
Args:
|
Args:
|
||||||
layout(QLayout): Layout to add the widgets to
|
grid_layout (QGridLayout): The grid layout to which widgets will be added.
|
||||||
items(list): List of items to add
|
items (list): List of items to add, where each item is a tuple (item_name, item_type).
|
||||||
signature(dict): Dictionary containing signature information for kwargs
|
signature (dict): Dictionary containing signature information for kwargs.
|
||||||
"""
|
"""
|
||||||
item_type, item_name = None, None
|
row_index = grid_layout.rowCount() # Get the next available row
|
||||||
widget_row_layout = QHBoxLayout()
|
for column_index, item in enumerate(items):
|
||||||
for row_idx, item in enumerate(items):
|
|
||||||
if signature:
|
if signature:
|
||||||
|
# If a signature is provided, extract type and name from it
|
||||||
kwarg_info = next((info for info in signature if info["name"] == item), None)
|
kwarg_info = next((info for info in signature if info["name"] == item), None)
|
||||||
if kwarg_info:
|
if kwarg_info:
|
||||||
item_type = kwarg_info.get("annotation", "_empty")
|
item_type = kwarg_info.get("annotation", "_empty")
|
||||||
item_name = item
|
item_name = item
|
||||||
else:
|
else:
|
||||||
|
# If no signature is provided, assume the item is a tuple of (name, type)
|
||||||
item_name, item_type = item
|
item_name, item_type = item
|
||||||
|
|
||||||
widget_class = self.WIDGET_HANDLER.get(item_type, None)
|
widget_class = self.WIDGET_HANDLER.get(item_type, None)
|
||||||
@ -195,10 +196,13 @@ class ScanControl(QWidget):
|
|||||||
) # TODO add type hinting!!!
|
) # TODO add type hinting!!!
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Generated widget by HANDLER
|
# Instantiate the widget and set some properties if necessary
|
||||||
widget = widget_class(self.scan_control_group)
|
widget = widget_class(self.scan_control_group)
|
||||||
widget_row_layout.addWidget(widget)
|
if isinstance(widget, QLineEdit):
|
||||||
layout.addLayout(widget_row_layout)
|
widget.setMinimumWidth(100) # Set a minimum width for QLineEdit if needed
|
||||||
|
|
||||||
|
# Add the widget to the grid layout at the calculated row and current column
|
||||||
|
grid_layout.addWidget(widget, row_index, column_index)
|
||||||
|
|
||||||
def clear_layout(self, layout: QLayout) -> None: # TODO like this probably
|
def clear_layout(self, layout: QLayout) -> None: # TODO like this probably
|
||||||
"""
|
"""
|
||||||
@ -219,24 +223,42 @@ class ScanControl(QWidget):
|
|||||||
sub_layout.setParent(None) # disown layout
|
sub_layout.setParent(None) # disown layout
|
||||||
sub_layout.deleteLater() # schedule layout for deletion
|
sub_layout.deleteLater() # schedule layout for deletion
|
||||||
|
|
||||||
|
def remove_last_row_from_grid_layout(self, grid_layout: QGridLayout) -> None:
|
||||||
|
"""
|
||||||
|
Removes the last row from the given grid layout.
|
||||||
|
Args:
|
||||||
|
grid_layout(QGridLayout): Layout to remove the last row from
|
||||||
|
"""
|
||||||
|
row_index = grid_layout.rowCount() - 1
|
||||||
|
# Find the actual last occupied row
|
||||||
|
while row_index > 0:
|
||||||
|
items_in_row = [
|
||||||
|
grid_layout.itemAtPosition(row_index, col)
|
||||||
|
for col in range(grid_layout.columnCount())
|
||||||
|
]
|
||||||
|
if not any(items_in_row): # If the row is empty, decrement the row index
|
||||||
|
row_index -= 1
|
||||||
|
else:
|
||||||
|
break # Found the last occupied row
|
||||||
|
|
||||||
|
# Proceed if we have more than one occupied row
|
||||||
|
if row_index > 2:
|
||||||
|
for column_index in range(grid_layout.columnCount()):
|
||||||
|
item = grid_layout.itemAtPosition(row_index, column_index)
|
||||||
|
if item is not None:
|
||||||
|
widget = item.widget()
|
||||||
|
if widget:
|
||||||
|
grid_layout.removeWidget(widget)
|
||||||
|
widget.deleteLater()
|
||||||
|
|
||||||
|
# Adjust the window size
|
||||||
|
self.window().resize(self.window().sizeHint())
|
||||||
|
|
||||||
def add_bundle(self) -> None:
|
def add_bundle(self) -> None:
|
||||||
"""Adds a bundle to the scan control layout"""
|
self.add_widgets_row_to_layout(self.args_layout, self.arg_input.items())
|
||||||
self.add_widgets_row_to_layout(
|
|
||||||
self.args_layout, self.arg_input.items()
|
|
||||||
) # Add first row of widgets
|
|
||||||
|
|
||||||
def remove_bundle(self) -> None:
|
def remove_bundle(self) -> None:
|
||||||
"""Removes the last bundle from the scan control layout"""
|
self.remove_last_row_from_grid_layout(self.args_layout)
|
||||||
last_bundle_index = self.args_layout.count() - 1 # Index of the last bundle
|
|
||||||
if last_bundle_index > 1: # Ensure that there is at least one bundle left
|
|
||||||
last_bundle_layout_item = self.args_layout.takeAt(last_bundle_index)
|
|
||||||
last_bundle_layout = last_bundle_layout_item.layout()
|
|
||||||
if last_bundle_layout:
|
|
||||||
self.clear_layout(last_bundle_layout) # Clear the last bundle layout
|
|
||||||
last_bundle_layout_item.setParent(None) # Disown layout item
|
|
||||||
last_bundle_layout_item.deleteLater() # Schedule layout item for deletion
|
|
||||||
|
|
||||||
self.window().resize(self.window().sizeHint()) # Resize window to fit contents
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
Reference in New Issue
Block a user