Source code for fluiddyn.util.paramcontainer_gui

"""Qt based GUI for parameters (:mod:`fluiddyn.util.paramcontainer_gui`)
========================================================================

Provides:

.. autoclass:: QtParamContainer
   :members:
   :private-members:

"""

import os
import subprocess
from copy import deepcopy

# try to be able to import without Qt implementation
try:
    from matplotlib.backends.qt_compat import QtCore, QtWidgets
except ImportError:
    if "GITLAB_CI" not in os.environ:
        raise
else:
    try:
        _fromUtf8 = QtCore.QString.fromUtf8
    except AttributeError:

        def _fromUtf8(s):
            return s

    try:
        _encoding = QtWidgets.QApplication.UnicodeUTF8

    except AttributeError:

        def _translate(context, text, disambig):
            return QtWidgets.QApplication.translate(context, text, disambig)

    else:

        def _translate(context, text, disambig):
            return QtWidgets.QApplication.translate(
                context, text, disambig, _encoding
            )


from fluiddyn.util import time_as_str


[docs] class QtParamContainer: """QWidget application framework for loading, editing, saving and launching a job from a ParamContainer object. """ def __init__( self, params, top=False, module_run_from_xml="fluidimage.run_from_xml" ): self.params = deepcopy(params) self.module_run_from_xml = module_run_from_xml full_tag_dot = params._make_full_tag() self.full_tag = full_tag_dot.replace(".", "_") self.labels = {} self.lines_edit = {} self.buttons = {} self.qt_params_children = {} key_attribs = params._get_key_attribs() tag_children = params._tag_children self.page_main = QtWidgets.QWidget() self.page_main.setObjectName(_fromUtf8("page_main_" + self.full_tag)) self.verticalLayout = QtWidgets.QVBoxLayout(self.page_main) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName( _fromUtf8("verticalLayout_" + self.full_tag) ) if self.params._contains_doc(): self.pushButton_doc = QtWidgets.QPushButton(self.page_main) self.pushButton_doc.setText("Display doc " + full_tag_dot) self.verticalLayout.addWidget(self.pushButton_doc) self.pushButton_doc.released.connect(self.params._print_docs) if len(key_attribs) > 0: self.page_attribs = QtWidgets.QWidget() self.page_attribs.setObjectName( _fromUtf8("page_attribs_" + self.full_tag) ) self.formLayout_attribs = QtWidgets.QFormLayout(self.page_attribs) self.formLayout_attribs.setContentsMargins(0, 0, 0, 0) self.formLayout_attribs.setObjectName( _fromUtf8("formLayout_" + self.full_tag) ) i = -1 for key in key_attribs: i += 1 label = self.labels[key] = QtWidgets.QLabel(self.page_attribs) label.setObjectName( _fromUtf8("label_" + self.full_tag + "_" + key) ) self.formLayout_attribs.setWidget( i, QtWidgets.QFormLayout.LabelRole, label ) line = self.lines_edit[key] = QtWidgets.QLineEdit( self.page_attribs ) line.setObjectName(_fromUtf8("line_" + self.full_tag + "_" + key)) self.formLayout_attribs.setWidget( i, QtWidgets.QFormLayout.FieldRole, line ) label.setText(_translate("MainWindow", key, None)) line.setText( _translate("MainWindow", repr(self.params[key]), None) ) if key == "path": i += 1 def choose_name(): fileName = QtWidgets.QFileDialog.getOpenFileName( self.page_attribs, "OpenFile" ) self.lines_edit["path"].setText("'" + fileName + "'") self.buttons[key] = QtWidgets.QPushButton(self.page_attribs) self.formLayout_attribs.setWidget( i, QtWidgets.QFormLayout.FieldRole, self.buttons[key] ) self.buttons[key].setText("Navigate to choose the path") self.buttons[key].released.connect(choose_name) self.verticalLayout.addWidget(self.page_attribs) if len(tag_children) > 0: self.toolBox = QtWidgets.QToolBox(self.page_main) for tag in tag_children: qtparam = self.qt_params_children[tag] = self.__class__( self.params[tag] ) self.toolBox.addItem( qtparam.page_main, _fromUtf8(full_tag_dot + "." + tag) ) self.verticalLayout.addWidget(self.toolBox) if top: self.pushButton_xml = QtWidgets.QPushButton(self.page_main) self.pushButton_xml.setText("Display as xml") self.verticalLayout.addWidget(self.pushButton_xml) self.pushButton_xml.released.connect(self.print_as_xml) self.pushButton_default = QtWidgets.QPushButton(self.page_main) self.pushButton_default.setText("Reset to default parameters") self.verticalLayout.addWidget(self.pushButton_default) self.pushButton_default.released.connect(self.reset_default_values) self.pushButton_launch = QtWidgets.QPushButton(self.page_main) self.pushButton_launch.setText("Launch computation") self.verticalLayout.addWidget(self.pushButton_launch) self.pushButton_launch.released.connect(self.launch) def set_values(self, params): for key in params._get_key_attribs(): self.lines_edit[key].setText( _translate("MainWindow", repr(params[key]), None) ) for tag in params._tag_children: self.qt_params_children[tag].set_values(params[tag]) def reset_default_values(self): self.set_values(self.params) def produce_params(self): params = deepcopy(self.params) self.modif_params(params) return params def print_as_xml(self): params = self.produce_params() params._print_as_xml() def modif_params(self, params): for key in self.params._get_key_attribs(): params[key] = eval(str(self.lines_edit[key].displayText())) for tag in self.params._tag_children: self.qt_params_children[tag].modif_params(params[tag]) def launch(self): params = self.produce_params() path_dir = "tmp_fluiddyn_params" if not os.path.exists(path_dir): os.mkdir(path_dir) path = params._save_as_xml( path_file=os.path.join( path_dir, params._tag + time_as_str() + ".xml" ), find_new_name=True, ) retcode = subprocess.call( ["python", "-m", self.module_run_from_xml, path] ) return retcode