# -*- coding: utf-8 -*-
"""
Copyright (c) 2021, the qudi developers. See the AUTHORS.md file at the top-level directory of this
distribution and on <https://github.com/Ulm-IQO/qudi-core/>
This file is part of qudi.
Qudi is free software: you can redistribute it and/or modify it under the terms of
the GNU Lesser General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
Qudi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with qudi.
If not, see <https://www.gnu.org/licenses/>.
"""
__all__ = ['ModuleSelector']
from PySide2 import QtWidgets, QtCore
from typing import Optional, Iterable, List, Mapping, Tuple, Dict
from qudi.tools.config_editor.tree_widgets import AvailableModulesTreeWidget
from qudi.tools.config_editor.tree_widgets import SelectedModulesTreeWidget
from qudi.util.widgets.separator_lines import HorizontalLine
[docs]
class ModuleSelector(QtWidgets.QDialog):
"""QDialog representing a selection editor for qudi modules to configure.
"""
[docs]
def __init__(self,
available_modules: Iterable[str],
named_modules: Optional[Mapping[str, str]] = None,
unnamed_modules: Optional[Iterable[str]] = None,
parent: Optional[QtWidgets.QWidget] = None
) -> None:
super().__init__(parent=parent)
self.setWindowTitle('Qudi Config Editor: Module Selection')
screen_size = QtWidgets.QApplication.instance().primaryScreen().availableSize()
self.resize(screen_size.width() // 3, screen_size.height() // 3)
# Create two customized QTreeWidgets. One for all available modules to select from and one
# for the selected modules.
self.available_treewidget = AvailableModulesTreeWidget(modules=available_modules)
self.selected_treewidget = SelectedModulesTreeWidget(named_modules=named_modules,
unnamed_modules=unnamed_modules)
# Create left side of splitter widget
left_widget = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
label = QtWidgets.QLabel('Available Modules')
font = label.font()
font.setPointSize(font.pointSize() + 4)
font.setBold(True)
label.setFont(font)
layout.addWidget(label)
layout.addWidget(self.available_treewidget)
left_widget.setLayout(layout)
# Create right side of splitter widget
right_widget = QtWidgets.QWidget()
layout = QtWidgets.QGridLayout()
right_widget.setLayout(layout)
label = QtWidgets.QLabel('Selected Modules')
label.setFont(font)
self.add_remote_button = QtWidgets.QPushButton('Add Remote Module')
self.add_custom_button = QtWidgets.QPushButton('Add Custom Module')
self.custom_module_lineedit = QtWidgets.QLineEdit()
self.custom_module_lineedit.setPlaceholderText('Custom module name (module.Class)')
self.base_selection_combobox = QtWidgets.QComboBox()
self.base_selection_combobox.addItems(['GUI', 'Logic', 'Hardware'])
self.add_remote_button.clicked.connect(self._add_remote_module_clicked)
self.add_custom_button.clicked.connect(self._add_custom_module_clicked)
layout.addWidget(label, 0, 0, 1, 3)
layout.addWidget(self.selected_treewidget, 1, 0, 1, 3)
label = QtWidgets.QLabel('Module Base:')
label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
layout.addWidget(label, 2, 0)
layout.addWidget(self.base_selection_combobox, 2, 1)
layout.addWidget(self.add_remote_button, 2, 2)
layout.addWidget(self.custom_module_lineedit, 3, 0, 1, 2)
layout.addWidget(self.add_custom_button, 3, 2)
layout.setColumnStretch(0, 1)
layout.setRowStretch(1, 1)
# set splitter as main widget
splitter = QtWidgets.QSplitter()
splitter.addWidget(left_widget)
splitter.addWidget(right_widget)
splitter.setCollapsible(0, False)
splitter.setCollapsible(1, False)
# Create buttonbox for this dialog
label = QtWidgets.QLabel(
'Include qudi modules by dragging them into the right field (press DEL to remove).'
)
label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
font = label.font()
font.setBold(True)
label.setFont(font)
self.button_box = QtWidgets.QDialogButtonBox(
QtWidgets.QDialogButtonBox.Cancel | QtWidgets.QDialogButtonBox.Ok
)
self.button_box.accepted.connect(self.accept)
self.button_box.rejected.connect(self.reject)
sub_layout = QtWidgets.QHBoxLayout()
sub_layout.addWidget(label)
sub_layout.addStretch()
sub_layout.addWidget(self.button_box)
# Add everything to the main layout
layout = QtWidgets.QVBoxLayout()
layout.addWidget(splitter)
layout.addWidget(HorizontalLine())
layout.addLayout(sub_layout)
layout.setStretch(0, 1)
self.setLayout(layout)
@property
def selected_modules(self) -> Tuple[Dict[str, str], List[str]]:
return self.selected_treewidget.modules
@QtCore.Slot()
def _add_remote_module_clicked(self) -> None:
base = self.base_selection_combobox.currentText().lower()
if base == 'gui':
raise ValueError('Unable to add remote module.\nGUI modules can not be remote modules.')
self.selected_treewidget.add_module(f'{base}.<REMOTE MODULE>')
@QtCore.Slot()
def _add_custom_module_clicked(self) -> None:
base = self.base_selection_combobox.currentText().lower()
module = self.custom_module_lineedit.text().strip()
if module:
self.selected_treewidget.add_module(f'{base}.{module}')