{"id":491,"date":"2020-10-10T19:22:16","date_gmt":"2020-10-10T10:22:16","guid":{"rendered":"https:\/\/shibaura-it.tokyo\/it-solution\/?p=491"},"modified":"2020-10-10T19:22:16","modified_gmt":"2020-10-10T10:22:16","slug":"asammdfgui-wrapper%e3%81%ae%e4%bd%9c%e6%88%90","status":"publish","type":"post","link":"https:\/\/shibaura-it.tokyo\/it-solution\/asammdfgui-wrapper%e3%81%ae%e4%bd%9c%e6%88%90\/","title":{"rendered":"asammdfgui wrapper\u306e\u4f5c\u6210"},"content":{"rendered":"<p>asammdf\u306e\u30ea\u30dd\u30b8\u30c8\u30ea\u306f\u65e5\u3005\u66f4\u65b0\u3055\u308c\u308b\u306e\u3068\u540c\u69d8\u306b\u3001asammdfgui\u306e\u30b3\u30fc\u30c9\u3082\u66f4\u65b0\u304c\u7d9a\u3044\u3066\u304a\u308a\u307e\u3059\u3002<br \/>\n\u72ec\u81ea\u306e\u6a5f\u80fd\u3092\u76db\u308a\u8fbc\u3080\u305f\u3081\u306b\u3001\u65e2\u5b58\u306e\u30b3\u30fc\u30c9\u3092\u7de8\u96c6\u3057\u3066\u3057\u307e\u3046\u3068\u3001\u3044\u3056asammdf\u306e\u30d1\u30c3\u30b1\u30fc\u30b8\u304c\u66f4\u65b0\u3055\u308c\u305f\u3068\u304d\u306b\u3001<br \/>\n\u72ec\u81ea\u306e\u7de8\u96c6\u90e8\u5206\u3068\u3001\u66f4\u65b0\u3055\u308c\u305f\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u30b3\u30f3\u30d5\u30ea\u30af\u30c8\u3084\u3001\u5dee\u5206\u306e\u4fee\u6b63\u306a\u3069\u591a\u5927\u306a\u52b4\u529b\u304c\u5fc5\u8981\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u3053\u306e\u3088\u3046\u306a\u3001\u554f\u984c\u3092\u56de\u907f\u3059\u308b\u305f\u3081\u3001asammdfgui\u306ewrapper\u3092\u4f5c\u6210\u3057\u3066\u3044\u304f\u3053\u3068\u3067\u3001<br \/>\n\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u66f4\u65b0\u3084\u3001\u7279\u5b9a\u306easammdf\u3078\u306e\u5bfe\u5fdc\u306a\u3069\u3001\u3088\u308a\u67d4\u8edf\u306a\u624b\u6cd5\u3092\u3068\u3063\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n<p>\u5177\u4f53\u7684\u306b\u306f\u3001\u30ed\u30fc\u30ab\u30eb\u306b\u30b3\u30d4\u30fc\u3057\u305fasammdf\u306e\u30d1\u30c3\u30b1\u30fc\u30b8\u3092\u76f4\u63a5\u5b9f\u884c\u3059\u308b\u547c\u3073\u51fa\u3057\u5143\u3068\u306a\u308bmain\u30d7\u30ed\u30b0\u30e9\u30e0\u304b\u3089\u3001<br \/>\n\u5fc5\u8981\u3068\u306a\u308b\u6a5f\u80fd\u3092\u5b9f\u88c5\u3057\u305fwidgets\u3092\u547c\u3073\u51fa\u3059\u3053\u3068\u3067\u3001\u65e2\u5b58\u306easammdfgui\u306e\u6a5f\u80fd\u306f\u305d\u306e\u307e\u307e\u5229\u7528\u3057\u3001<br \/>\n\u65b0\u305f\u306b\u6a5f\u80fd\u3092\u8ffd\u52a0\u3057\u305f\u5834\u5408\u306f\u3001\u3053\u306ewidgets\u304b\u3089\u6a5f\u80fd\u3092\u547c\u3073\u51fa\u3059\u3053\u3068\u3067\u3001\u65e2\u5b58\u306easammdfgui\u306e\u6a5f\u80fd\u3068\u3001<br \/>\n\u8ffd\u52a0\u3057\u305f\u6a5f\u80fd\u3092\u5171\u5b58\u3055\u305b\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n<p>\u305d\u308c\u3067\u306f\u3001\u5b9f\u969b\u306b\u4f5c\u696d\u3092\u59cb\u3081\u307e\u3059\u3002<\/p>\n<p>\u307e\u305a\u3001\u4f5c\u696d\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306basammdf\u306e\u30d1\u30c3\u30b1\u30fc\u30b8\u3092\u5168\u3066\u30b3\u30d4\u30fc\u3057\u3066\u304d\u307e\u3059\u3002<br \/>\n\u3053\u3053\u3067\u306f\u3001\u4f8b\u3068\u3057\u3066\u201dd:\u00a5Python\u00a5GUI_Portable\u201d\u3068\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p><a href=\"https:\/\/shibaura-it.tokyo\/it-solution\/wp\/wp-content\/uploads\/2020\/10\/2020-10-10_19h03_01.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-492\" src=\"https:\/\/shibaura-it.tokyo\/it-solution\/wp\/wp-content\/uploads\/2020\/10\/2020-10-10_19h03_01-600x393.jpg\" alt=\"\" width=\"600\" height=\"393\" srcset=\"https:\/\/shibaura-it.tokyo\/it-solution\/wp\/wp-content\/uploads\/2020\/10\/2020-10-10_19h03_01-600x393.jpg 600w, https:\/\/shibaura-it.tokyo\/it-solution\/wp\/wp-content\/uploads\/2020\/10\/2020-10-10_19h03_01-768x503.jpg 768w, https:\/\/shibaura-it.tokyo\/it-solution\/wp\/wp-content\/uploads\/2020\/10\/2020-10-10_19h03_01.jpg 1024w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<p>\u7d9a\u3044\u3066\u3001\u4e0b\u8a18\u306e\u30b3\u30fc\u30c9\u3092\u201dd:\u00a5Python\u00a5GUI_Portable\u00a5gui\u201d\u306b\u201dGUI_Sample.py\u201d\u3068\u3057\u3066\u4fdd\u5b58\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"lang:python decode:true \" title=\"GUI_Sample.py\"># -*- coding: utf-8 -*-\r\nimport argparse\r\nimport sys\r\n\r\nfrom PyQt5 import QtWidgets\r\n\r\nimport os\r\nsys.path.append(os.path.abspath(\"..\"))\r\nprint(os.path.abspath(\"..\"))\r\n\r\nfrom GUI_Portable.gui.utils import excepthook\r\nfrom GUI_Portable.gui.widgets.GUI_main import MainWindow\r\n \r\nsys.excepthook = excepthook\r\n\r\ndef _cmd_line_parser():\r\n    \"\"\"\r\n    \"\"\"\r\n\r\n    parser = argparse.ArgumentParser()\r\n    parser.add_argument(\r\n        \"--measurements\", nargs=\"*\", help=\"list of measurement files\",\r\n    )\r\n    return parser\r\n\r\ndef main(measurements=None):\r\n    parser = _cmd_line_parser()\r\n    args = parser.parse_args(sys.argv[1:])\r\n    app = QtWidgets.QApplication(sys.argv)\r\n    app.setOrganizationName(\"UNI-MDF\")\r\n    app.setOrganizationDomain(\"UNI-MDF\")\r\n    app.setApplicationName(\"UNI-MDF\")\r\n    main = MainWindow(args.measurements)\r\n    app.setStyle(QtWidgets.QStyleFactory.create(\"Fusion\"))\r\n    window = MainWindow()\r\n    window.show()\r\n    sys.exit(app.exec_())\r\n\r\n    app.exec_()\r\n\r\nif __name__==\"__main__\":\r\n    main()<\/pre>\n<p>\u7d9a\u3044\u3066\u3001\u201dd:\u00a5Python\u00a5GUI_Portable\u00a5gui\u00a5widgets\u201d\u306b\u4e0b\u8a18\u30b3\u30fc\u30c9\u3092\u201dGUI_Main.py\u201d\u3068\u3057\u3066\u4fdd\u5b58\u3057\u307e\u3059\u3002<br \/>\n\u79c1\u306e\u76ee\u7684\u306e\u30c7\u30b6\u30a4\u30f3\u306b\u5408\u308f\u305b\u3066\u201dMain.py\u201d\u304b\u3089\u3001\u3044\u304f\u3064\u304b\u306e\u30b3\u30fc\u30c9\u3092\u524a\u9664\u3057\u305f\u3082\u306e\u3067\u3059\u3002<\/p>\n<pre class=\"lang:python decode:true \" title=\"GUI_Main.py\"># -*- coding: utf-8 -*-\r\nfrom functools import partial\r\nimport gc\r\nimport json\r\nimport sys\r\nimport os\r\n\r\nfrom pathlib import Path\r\nfrom natsort import natsorted\r\nfrom PyQt5 import QtCore, QtGui, QtWidgets\r\nimport pyqtgraph as pg\r\n\r\nfrom ..dialogs.multi_search import MultiSearch\r\nfrom ..ui.main_window import Ui_PyMDFMainWindow\r\n\r\nfrom ..widgets.file import FileWidget\r\nfrom .mdi_area import MdiAreaWidget, WithMDIArea\r\nfrom .numeric import Numeric\r\nfrom .plot import Plot\r\nfrom .tabular import Tabular\r\n\r\nclass MainWindow(WithMDIArea, Ui_PyMDFMainWindow, QtWidgets.QMainWindow):\r\n    def __init__(self, files=None, *args, **kwargs):\r\n        super(Ui_PyMDFMainWindow, self).__init__(*args, **kwargs)\r\n        WithMDIArea.__init__(self)\r\n        self.setupUi(self)\r\n        self._settings = QtCore.QSettings()\r\n        self._light_palette = self.palette()\r\n\r\n        self.ignore_value2text_conversions = self._settings.value(\r\n            \"ignore_value2text_conversions\", False, type=bool\r\n        )\r\n\r\n        widget = QtWidgets.QWidget()\r\n        layout = QtWidgets.QVBoxLayout()\r\n        widget.setLayout(layout)\r\n\r\n        self.mdi_area = MdiAreaWidget(self)\r\n        self.mdi_area.add_window_request.connect(self.add_window)\r\n        self.mdi_area.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)\r\n        self.mdi_area.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)\r\n\r\n        layout.addWidget(self.mdi_area)\r\n\r\n        self.stackedWidget.addWidget(widget)\r\n        self.stackedWidget.setCurrentIndex(0)\r\n\r\n        self.progress = None\r\n\r\n        menu = self.menubar.addMenu(\"File\")\r\n        open_group = QtWidgets.QActionGroup(self)\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(QtGui.QPixmap(\":\/open.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off)\r\n\r\n        action = QtWidgets.QAction(icon, \"Open\", menu)\r\n        action.triggered.connect(self.open)\r\n        action.setShortcut(QtGui.QKeySequence(\"Ctrl+O\"))\r\n        open_group.addAction(action)\r\n\r\n        open_group.addAction(action)\r\n\r\n        menu.addActions(open_group.actions())\r\n\r\n        menu.addSeparator()\r\n\r\n        open_group = QtWidgets.QActionGroup(self)\r\n        action = QtWidgets.QAction(icon, \"Open configuration\", menu)\r\n        action.triggered.connect(self.open_configuration)\r\n        open_group.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(QtGui.QPixmap(\":\/save.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off)\r\n        action = QtWidgets.QAction(icon, \"Save configuration\", menu)\r\n        action.triggered.connect(self.save_configuration)\r\n        open_group.addAction(action)\r\n\r\n        menu.addActions(open_group.actions())\r\n\r\n        # mode_actions\r\n        mode_actions = QtWidgets.QActionGroup(self)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(QtGui.QPixmap(\":\/file.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off)\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\".format(\"Single files\"), menu)\r\n        action.triggered.connect(partial(self.stackedWidget.setCurrentIndex, 0))\r\n        mode_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(QtGui.QPixmap(\":\/list.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off)\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\".format(\"Batch processing\"), menu)\r\n        action.triggered.connect(partial(self.stackedWidget.setCurrentIndex, 1))\r\n        mode_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(\r\n            QtGui.QPixmap(\":\/compare.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off\r\n        )\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\".format(\"Comparison\"), menu)\r\n        action.triggered.connect(partial(self.stackedWidget.setCurrentIndex, 2))\r\n        mode_actions.addAction(action)\r\n\r\n        menu = QtWidgets.QMenu(\"Mode\", self.menubar)\r\n        menu.addActions(mode_actions.actions())\r\n        self.menubar.addMenu(menu)\r\n\r\n        menu = QtWidgets.QMenu(\"Settings\", self.menubar)\r\n        self.menubar.addMenu(menu)\r\n\r\n        # sub plots\r\n        subplot_action = QtWidgets.QAction(\"Sub-plots\", menu)\r\n        subplot_action.setCheckable(True)\r\n\r\n        state = self._settings.value(\"subplots\", False, type=bool)\r\n        subplot_action.toggled.connect(self.set_subplot_option)\r\n        subplot_action.triggered.connect(self.set_subplot_option)\r\n        subplot_action.setChecked(state)\r\n        menu.addAction(subplot_action)\r\n\r\n        # Link sub-plots X-axis\r\n        subplot_action = QtWidgets.QAction(\"Link sub-plots X-axis\", menu)\r\n        subplot_action.setCheckable(True)\r\n        state = self._settings.value(\"subplots_link\", False, type=bool)\r\n        subplot_action.toggled.connect(self.set_subplot_link_option)\r\n        subplot_action.setChecked(state)\r\n        menu.addAction(subplot_action)\r\n\r\n        # Link sub-plots X-axis\r\n        subplot_action = QtWidgets.QAction(\"Ignore value2text conversions\", menu)\r\n        subplot_action.setCheckable(True)\r\n        subplot_action.toggled.connect(self.set_ignore_value2text_conversions_option)\r\n        subplot_action.setChecked(self.ignore_value2text_conversions)\r\n        menu.addAction(subplot_action)\r\n\r\n        # plot background\r\n        plot_background_option = QtWidgets.QActionGroup(self)\r\n\r\n        for option in (\"Black\", \"White\"):\r\n\r\n            action = QtWidgets.QAction(option, menu)\r\n            action.setCheckable(True)\r\n            plot_background_option.addAction(action)\r\n            action.triggered.connect(partial(self.set_plot_background, option))\r\n\r\n            if option == self._settings.value(\"plot_background\", \"Black\"):\r\n                action.setChecked(True)\r\n                action.triggered.emit()\r\n\r\n        submenu = QtWidgets.QMenu(\"Plot background\", self.menubar)\r\n        submenu.addActions(plot_background_option.actions())\r\n        menu.addMenu(submenu)\r\n\r\n        # plot X axis display mode\r\n        plot_xaxis_option = QtWidgets.QActionGroup(self)\r\n\r\n        for option in (\"seconds\", \"time\", \"date\"):\r\n\r\n            action = QtWidgets.QAction(option, menu)\r\n            action.setCheckable(True)\r\n            plot_xaxis_option.addAction(action)\r\n            action.triggered.connect(partial(self.set_plot_xaxis, option))\r\n\r\n            if option == self._settings.value(\"plot_xaxis\", \"seconds\"):\r\n                action.setChecked(True)\r\n                action.triggered.emit()\r\n\r\n        submenu = QtWidgets.QMenu(\"Plot X axis\", self.menubar)\r\n        submenu.addActions(plot_xaxis_option.actions())\r\n        menu.addMenu(submenu)\r\n\r\n\r\n\r\n        # plot option menu\r\n        plot_actions = QtWidgets.QActionGroup(self)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(QtGui.QPixmap(\":\/fit.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off)\r\n        fullscreen = QtWidgets.QAction(icon, f\"{'Fullscreen': &lt;20}\\tF8\", menu)\r\n        fullscreen.triggered.connect(self.toggle_fullscreen)\r\n        fullscreen.setShortcut(QtCore.Qt.Key_F8)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(QtGui.QPixmap(\":\/fit.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off)\r\n        action = QtWidgets.QAction(icon, f\"{'Fit trace': &lt;20}\\tF\", menu)\r\n        action.triggered.connect(partial(self.plot_action, key=QtCore.Qt.Key_F))\r\n        action.setShortcut(QtCore.Qt.Key_F)\r\n        plot_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(QtGui.QPixmap(\":\/grid.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off)\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\\tG\".format(\"Grid\"), menu)\r\n        action.triggered.connect(partial(self.plot_action, key=QtCore.Qt.Key_G))\r\n        action.setShortcut(QtCore.Qt.Key_G)\r\n        plot_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(QtGui.QPixmap(\":\/home.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off)\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\\tH\".format(\"Home\"), menu)\r\n        action.triggered.connect(partial(self.plot_action, key=QtCore.Qt.Key_H))\r\n        action.setShortcut(QtCore.Qt.Key_H)\r\n        plot_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(\r\n            QtGui.QPixmap(\":\/list2.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off\r\n        )\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\\tS\".format(\"Stack\"), menu)\r\n        action.triggered.connect(partial(self.plot_action, key=QtCore.Qt.Key_S))\r\n        action.setShortcut(QtCore.Qt.Key_S)\r\n        plot_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(\r\n            QtGui.QPixmap(\":\/zoom-in.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off\r\n        )\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\\tI\".format(\"Zoom in\"), menu)\r\n        action.triggered.connect(partial(self.plot_action, key=QtCore.Qt.Key_I))\r\n        action.setShortcut(QtCore.Qt.Key_I)\r\n        plot_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(\r\n            QtGui.QPixmap(\":\/zoom-out.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off\r\n        )\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\\tO\".format(\"Zoom out\"), menu)\r\n        action.triggered.connect(partial(self.plot_action, key=QtCore.Qt.Key_O))\r\n        action.setShortcut(QtCore.Qt.Key_O)\r\n        plot_actions.addAction(action)\r\n\r\n        action = QtWidgets.QAction(\"{: &lt;20}\\t.\".format(\"Toggle dots\"), menu)\r\n        action.triggered.connect(partial(self.toggle_dots, key=QtCore.Qt.Key_Period))\r\n        action.setShortcut(QtCore.Qt.Key_Period)\r\n        plot_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(QtGui.QPixmap(\":\/plus.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off)\r\n        action = QtWidgets.QAction(\r\n            icon, \"{: &lt;20}\\tIns\".format(\"Insert computation\"), menu\r\n        )\r\n        action.triggered.connect(partial(self.plot_action, key=QtCore.Qt.Key_Insert))\r\n        action.setShortcut(QtCore.Qt.Key_Insert)\r\n        plot_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(QtGui.QPixmap(\":\/save.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off)\r\n        action = QtWidgets.QAction(\r\n            icon, \"{: &lt;20}\\tCtrl+S\".format(\"Save active subplot channels\"), menu\r\n        )\r\n        action.triggered.connect(\r\n            partial(\r\n                self.plot_action,\r\n                key=QtCore.Qt.Key_S,\r\n                modifier=QtCore.Qt.ControlModifier,\r\n            )\r\n        )\r\n        action.setShortcut(QtGui.QKeySequence(\"Ctrl+S\"))\r\n        plot_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(QtGui.QPixmap(\":\/save.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off)\r\n        action = QtWidgets.QAction(\r\n            icon, \"{: &lt;20}\\tCtrl+Shift+S\".format(\"Save all subplot channels\"), menu\r\n        )\r\n        action.triggered.connect(self.save_all_subplots)\r\n        action.setShortcut(QtGui.QKeySequence(\"Ctrl+Shift+S\"))\r\n        plot_actions.addAction(action)\r\n\r\n        # values display\r\n\r\n        display_format_actions = QtWidgets.QActionGroup(self)\r\n\r\n        action = QtWidgets.QAction(\"{: &lt;20}\\tCtrl+H\".format(\"Hex\"), menu)\r\n        action.triggered.connect(\r\n            partial(\r\n                self.plot_action,\r\n                key=QtCore.Qt.Key_H,\r\n                modifier=QtCore.Qt.ControlModifier,\r\n            )\r\n        )\r\n        action.setShortcut(QtGui.QKeySequence(\"Ctrl+H\"))\r\n        display_format_actions.addAction(action)\r\n\r\n        action = QtWidgets.QAction(\"{: &lt;20}\\tCtrl+B\".format(\"Bin\"), menu)\r\n        action.triggered.connect(\r\n            partial(\r\n                self.plot_action,\r\n                key=QtCore.Qt.Key_B,\r\n                modifier=QtCore.Qt.ControlModifier,\r\n            )\r\n        )\r\n        action.setShortcut(QtGui.QKeySequence(\"Ctrl+B\"))\r\n        display_format_actions.addAction(action)\r\n\r\n        action = QtWidgets.QAction(\"{: &lt;20}\\tCtrl+P\".format(\"Physical\"), menu)\r\n        action.triggered.connect(\r\n            partial(\r\n                self.plot_action,\r\n                key=QtCore.Qt.Key_P,\r\n                modifier=QtCore.Qt.ControlModifier,\r\n            )\r\n        )\r\n        action.setShortcut(QtGui.QKeySequence(\"Ctrl+P\"))\r\n        display_format_actions.addAction(action)\r\n\r\n        # scaled display\r\n\r\n        samples_format_actions = QtWidgets.QActionGroup(self)\r\n\r\n        action = QtWidgets.QAction(\"{: &lt;20}\\tAlt+R\".format(\"Raw samples\"), menu)\r\n        action.triggered.connect(\r\n            partial(\r\n                self.plot_action, key=QtCore.Qt.Key_R, modifier=QtCore.Qt.AltModifier,\r\n            )\r\n        )\r\n        action.setShortcut(QtGui.QKeySequence(\"Alt+R\"))\r\n        samples_format_actions.addAction(action)\r\n\r\n        action = QtWidgets.QAction(\"{: &lt;20}\\tAlt+S\".format(\"Scaled samples\"), menu)\r\n        action.triggered.connect(\r\n            partial(\r\n                self.plot_action, key=QtCore.Qt.Key_S, modifier=QtCore.Qt.AltModifier,\r\n            )\r\n        )\r\n        action.setShortcut(QtGui.QKeySequence(\"Alt+S\"))\r\n        samples_format_actions.addAction(action)\r\n\r\n        # info\r\n\r\n        info = QtWidgets.QActionGroup(self)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(QtGui.QPixmap(\":\/info.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off)\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\\tM\".format(\"Statistics\"), menu)\r\n        action.triggered.connect(partial(self.plot_action, key=QtCore.Qt.Key_M))\r\n        action.setShortcut(QtGui.QKeySequence(\"M\"))\r\n        info.addAction(action)\r\n\r\n        # sub_plots\r\n\r\n        subs = QtWidgets.QActionGroup(self)\r\n\r\n        action = QtWidgets.QAction(\"{: &lt;20}\\tShift+C\".format(\"Cascade sub-plots\"), menu)\r\n        action.triggered.connect(partial(self.show_sub_windows, mode=\"cascade\"))\r\n        action.setShortcut(QtGui.QKeySequence(\"Shift+C\"))\r\n        subs.addAction(action)\r\n\r\n        action = QtWidgets.QAction(\r\n            \"{: &lt;20}\\tShift+T\".format(\"Tile sub-plots in a grid\"), menu\r\n        )\r\n        action.triggered.connect(partial(self.show_sub_windows, mode=\"tile\"))\r\n        action.setShortcut(QtGui.QKeySequence(\"Shift+T\"))\r\n        subs.addAction(action)\r\n\r\n        action = QtWidgets.QAction(\r\n            \"{: &lt;20}\\tShift+V\".format(\"Tile sub-plots vertically\"), menu\r\n        )\r\n        action.triggered.connect(partial(self.show_sub_windows, mode=\"tile vertically\"))\r\n        action.setShortcut(QtGui.QKeySequence(\"Shift+V\"))\r\n        subs.addAction(action)\r\n\r\n        action = QtWidgets.QAction(\r\n            \"{: &lt;20}\\tShift+H\".format(\"Tile sub-plots horizontally\"), menu\r\n        )\r\n        action.triggered.connect(\r\n            partial(self.show_sub_windows, mode=\"tile horizontally\")\r\n        )\r\n        action.setShortcut(QtGui.QKeySequence(\"Shift+H\"))\r\n        subs.addAction(action)\r\n\r\n        action = QtWidgets.QAction(\r\n            \"{: &lt;20}\\tShift+F\".format(\"Toggle sub-plots frames\"), menu\r\n        )\r\n        action.triggered.connect(self.toggle_frames)\r\n        action.setShortcut(QtGui.QKeySequence(\"Shift+F\"))\r\n        subs.addAction(action)\r\n\r\n        action = QtWidgets.QAction(\r\n            \"{: &lt;20}\\tShift+L\".format(\"Toggle channel list\"), menu\r\n        )\r\n        action.triggered.connect(self.toggle_channels_list)\r\n        action.setShortcut(QtGui.QKeySequence(\"Shift+L\"))\r\n        subs.addAction(action)\r\n\r\n        # cursors\r\n        cursors_actions = QtWidgets.QActionGroup(self)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(\r\n            QtGui.QPixmap(\":\/cursor.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off\r\n        )\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\\tC\".format(\"Cursor\"), menu)\r\n        action.triggered.connect(partial(self.plot_action, key=QtCore.Qt.Key_C))\r\n        action.setShortcut(QtCore.Qt.Key_C)\r\n        cursors_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(\r\n            QtGui.QPixmap(\":\/right.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off\r\n        )\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\\t\u2190\".format(\"Move cursor left\"), menu)\r\n        action.triggered.connect(partial(self.plot_action, key=QtCore.Qt.Key_Left))\r\n        action.setShortcut(QtCore.Qt.Key_Left)\r\n        cursors_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(QtGui.QPixmap(\":\/left.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off)\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\\t\u2192\".format(\"Move cursor right\"), menu)\r\n        action.triggered.connect(partial(self.plot_action, key=QtCore.Qt.Key_Right))\r\n        action.setShortcut(QtCore.Qt.Key_Right)\r\n        cursors_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(\r\n            QtGui.QPixmap(\":\/range.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off\r\n        )\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\\tR\".format(\"Range\"), menu)\r\n        action.triggered.connect(partial(self.plot_action, key=QtCore.Qt.Key_R))\r\n        action.setShortcut(QtCore.Qt.Key_R)\r\n        cursors_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(\r\n            QtGui.QPixmap(\":\/lock_range.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off\r\n        )\r\n        action = QtWidgets.QAction(icon, \"{: &lt;20}\\tY\".format(\"Lock\/unlock range\"), menu)\r\n        action.triggered.connect(partial(self.plot_action, key=QtCore.Qt.Key_Y))\r\n        action.setShortcut(QtCore.Qt.Key_Y)\r\n        cursors_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        icon.addPixmap(\r\n            QtGui.QPixmap(\":\/comments.png\"), QtGui.QIcon.Normal, QtGui.QIcon.Off\r\n        )\r\n        action = QtWidgets.QAction(\r\n            icon, \"{: &lt;20}\\tCtrl+I\".format(\"Insert cursor comment\"), menu\r\n        )\r\n        action.triggered.connect(\r\n            partial(\r\n                self.plot_action,\r\n                key=QtCore.Qt.Key_I,\r\n                modifier=QtCore.Qt.ControlModifier,\r\n            )\r\n        )\r\n        action.setShortcut(QtGui.QKeySequence(\"Ctrl+I\"))\r\n        cursors_actions.addAction(action)\r\n\r\n        icon = QtGui.QIcon()\r\n        action = QtWidgets.QAction(\r\n            \"{: &lt;20}\\tAlt+I\".format(\"Toggle trigger texts\"), menu\r\n        )\r\n        action.triggered.connect(\r\n            partial(\r\n                self.plot_action, key=QtCore.Qt.Key_I, modifier=QtCore.Qt.AltModifier,\r\n            )\r\n        )\r\n        action.setShortcut(QtGui.QKeySequence(\"Alt+I\"))\r\n        cursors_actions.addAction(action)\r\n\r\n        self.plot_menu = QtWidgets.QMenu(\"Plot\", self.menubar)\r\n        self.plot_menu.addAction(fullscreen)\r\n        self.plot_menu.addSeparator()\r\n        self.plot_menu.addActions(plot_actions.actions())\r\n        self.plot_menu.addSeparator()\r\n        self.plot_menu.addActions(cursors_actions.actions())\r\n        self.plot_menu.addSeparator()\r\n        self.plot_menu.addActions(display_format_actions.actions())\r\n        self.plot_menu.addSeparator()\r\n        self.plot_menu.addActions(samples_format_actions.actions())\r\n        self.plot_menu.addSeparator()\r\n        self.plot_menu.addActions(subs.actions())\r\n        self.plot_menu.addSeparator()\r\n        self.plot_menu.addActions(info.actions())\r\n        self.menubar.addMenu(self.plot_menu)\r\n        self.with_dots = self._settings.value(\"dots\", False, type=bool)\r\n\r\n        self.set_subplot_option(self._settings.value(\"subplots\", \"Disabled\"))\r\n        self.set_subplot_link_option(self._settings.value(\"subplots_link\", \"Disabled\"))\r\n\r\n    def plot_action(self, key, modifier=QtCore.Qt.NoModifier):\r\n        event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress, key, modifier)\r\n        if self.stackedWidget.currentIndex() == 0:\r\n            widget = self.files.currentWidget()\r\n            if widget and widget.get_current_plot():\r\n                widget.get_current_plot().keyPressEvent(event)\r\n        elif self.stackedWidget.currentIndex() == 2:\r\n            widget = self\r\n            if widget and widget.get_current_plot():\r\n                widget.get_current_plot().keyPressEvent(event)\r\n\r\n    def toggle_dots(self, key):\r\n        self.with_dots = not self.with_dots\r\n        self._settings.setValue(\"dots\", self.with_dots)\r\n\r\n        count = self.files.count()\r\n\r\n        for i in range(count):\r\n            self.files.widget(i).set_line_style(with_dots=self.with_dots)\r\n\r\n        self.set_line_style(with_dots=self.with_dots)\r\n\r\n    def show_sub_windows(self, mode):\r\n\r\n        if self.stackedWidget.currentIndex() == 0:\r\n\r\n            widget = self.files.currentWidget()\r\n            if widget:\r\n                if mode == \"tile\":\r\n                    widget.mdi_area.tileSubWindows()\r\n                elif mode == \"cascade\":\r\n                    widget.mdi_area.cascadeSubWindows()\r\n                elif mode == \"tile vertically\":\r\n                    widget.mdi_area.tile_vertically()\r\n                elif mode == \"tile horizontally\":\r\n                    widget.mdi_area.tile_horizontally()\r\n\r\n        else:\r\n            widget = self\r\n            if widget:\r\n                if mode == \"tile\":\r\n                    widget.mdi_area.tileSubWindows()\r\n                elif mode == \"cascade\":\r\n                    widget.mdi_area.cascadeSubWindows()\r\n                elif mode == \"tile vertically\":\r\n                    widget.mdi_area.tile_vertically()\r\n                elif mode == \"tile horizontally\":\r\n                    widget.mdi_area.tile_horizontally()\r\n\r\n    def set_subplot_option(self, state):\r\n        if isinstance(state, str):\r\n            state = True if state == \"true\" else False\r\n        self.set_subplots(state)\r\n        self._settings.setValue(\"subplots\", state)\r\n\r\n        count = self.files.count()\r\n\r\n        for i in range(count):\r\n            self.files.widget(i).set_subplots(state)\r\n\r\n    def set_plot_background(self, option):\r\n        self._settings.setValue(\"plot_background\", option)\r\n        if option == \"Black\":\r\n            pg.setConfigOption(\"background\", \"k\")\r\n            pg.setConfigOption(\"foreground\", \"w\")\r\n        else:\r\n            pg.setConfigOption(\"background\", \"w\")\r\n            pg.setConfigOption(\"foreground\", \"k\")\r\n\r\n    def set_plot_xaxis(self, option):\r\n        self._settings.setValue(\"plot_xaxis\", option)\r\n        if option == \"seconds\":\r\n            fmt = \"phys\"\r\n        elif option == \"time\":\r\n            fmt = \"time\"\r\n        elif option == \"date\":\r\n            fmt = \"date\"\r\n\r\n        if self.stackedWidget.currentIndex() == 0:\r\n            widget = self.files.currentWidget()\r\n        elif self.stackedWidget.currentIndex() == 2:\r\n            widget = self\r\n        else:\r\n            widget = None\r\n        if widget:\r\n            plot = widget.get_current_plot()\r\n            if plot:\r\n                widget.get_current_plot().plot.x_axis.format = fmt\r\n                widget.get_current_plot().plot.x_axis.updateAutoSIPrefix()\r\n                if plot.plot.cursor1 is not None:\r\n                    plot.cursor_moved()\r\n                if plot.plot.region is not None:\r\n                    plot.range_modified()\r\n\r\n    def set_subplot_link_option(self, state):\r\n        if isinstance(state, str):\r\n            state = True if state == \"true\" else False\r\n        self.set_subplots_link(state)\r\n        self._settings.setValue(\"subplots_link\", state)\r\n        count = self.files.count()\r\n\r\n        for i in range(count):\r\n            self.files.widget(i).set_subplots_link(self.subplots_link)\r\n\r\n    def set_ignore_value2text_conversions_option(self, state):\r\n        if isinstance(state, str):\r\n            state = True if state == \"true\" else False\r\n        self.ignore_value2text_conversions = state\r\n        self._settings.setValue(\"ignore_value2text_conversions\", state)\r\n        count = self.files.count()\r\n\r\n        for i in range(count):\r\n            self.files.widget(i).ignore_value2text_conversions = state\r\n        self.batch.ignore_value2text_conversions = state\r\n\r\n    def open(self, event):\r\n        if self.stackedWidget.currentIndex() in (0, 2):\r\n            self.open_file(event)\r\n            self.stackedWidget.setCurrentIndex(0)\r\n        else:\r\n            self.open_batch_files(event)\r\n\r\n    def _open_file(self, file_name):\r\n        file_name = Path(file_name)\r\n        index = self.files.count()\r\n\r\n        try:\r\n            widget = FileWidget(\r\n                file_name,\r\n                self.with_dots,\r\n                self.subplots,\r\n                self.subplots_link,\r\n                self.ignore_value2text_conversions,\r\n                self,\r\n            )\r\n        except:\r\n            raise\r\n        else:\r\n            self.files.addTab(widget, file_name.name)\r\n            self.files.setTabToolTip(index, str(file_name))\r\n            self.files.setCurrentIndex(index)\r\n            widget.open_new_file.connect(self._open_file)\r\n            widget.full_screen_toggled.connect(self.toggle_fullscreen)\r\n\r\n    def open_file(self, event):\r\n        file_names, _ = QtWidgets.QFileDialog.getOpenFileNames(\r\n            self,\r\n            \"Select measurement file\",\r\n            self._settings.value(\"last_opened_path\", \"\", str),\r\n            \"MDF v3 (*.dat *.mdf);;MDF v4(*.mf4);;All files (*.dat *.mdf *.mf4 *.zip)\",\r\n            \"All files (*.dat *.mdf *.mf4 *.zip)\",\r\n        )\r\n\r\n        if file_names:\r\n            self._settings.setValue(\"last_opened_path\", file_names[0])\r\n            gc.collect()\r\n\r\n        for file_name in natsorted(file_names):\r\n            self._open_file(file_name)\r\n\r\n    def toggle_fullscreen(self):\r\n        if self.files.count() &gt; 0 or self.fullscreen is not None:\r\n            if self.fullscreen is None:\r\n                index = self.files.currentIndex()\r\n                widget = self.files.widget(index)\r\n                if widget:\r\n                    widget.setParent(None)\r\n                    widget.showFullScreen()\r\n                    widget.autofit_sub_plots()\r\n                    self.fullscreen = widget, index\r\n            else:\r\n                widget, index = self.fullscreen\r\n                file_name = str(Path(widget.mdf.name).name)\r\n                self.files.insertTab(index, widget, file_name)\r\n                self.files.setTabToolTip(index, str(widget.mdf.name))\r\n                self.files.setCurrentIndex(index)\r\n                self.fullscreen = None\r\n                self.activateWindow()\r\n\r\n                widget.autofit_sub_plots()\r\n\r\n                self.with_dots = widget.with_dots\r\n                self._settings.setValue(\"dots\", self.with_dots)\r\n\r\n                count = self.files.count()\r\n\r\n                for i in range(count):\r\n                    self.files.widget(i).set_line_style(with_dots=self.with_dots)\r\n\r\n    def toggle_frames(self, event=None):\r\n        count = self.files.count()\r\n\r\n        for i in range(count):\r\n            self.files.widget(i).toggle_frames()\r\n\r\n    def toggle_channels_list(self, event=None):\r\n        if self.stackedWidget.currentIndex() == 0:\r\n            widget = self.files.currentWidget()\r\n            event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress, QtCore.Qt.Key_L, QtCore.Qt.ShiftModifier)\r\n            if widget:\r\n                widget.keyPressEvent(event)\r\n\r\n    def open_configuration(self, event=None):\r\n        if self.stackedWidget.currentIndex() == 0:\r\n            widget = self.files.currentWidget()\r\n            if widget:\r\n                widget.load_channel_list()\r\n\r\n    def save_configuration(self, event=None):\r\n        if self.stackedWidget.currentIndex() == 0:\r\n            widget = self.files.currentWidget()\r\n            if widget:\r\n                widget.save_channel_list()\r\n<\/pre>\n<p>\u3053\u308c\u3067\u3001\u201dd:\u00a5Python\u00a5GUI_Portable\u00a5gui\u00a5GUI_Sample.py\u201d\u3092\u5b9f\u884c\u3059\u308b\u3068\u3001<br \/>\n\u7de8\u96c6\u3057\u305f&#8221;GUI_Main.py&#8221;\u304c\u5b9f\u884c\u3055\u308c\u308b\u305f\u3081\u3001\u65e2\u5b58\u306easammdfgui\u3068\u306f\u201dFile\u201d\u306e\u30e1\u30cb\u30e5\u30fc\u5185\u5bb9\u304c\u7570\u306a\u3063\u305f\u3001<br \/>\nGUI\u304c\u8d77\u52d5\u3057\u307e\u3059\u3002<\/p>\n<p><a href=\"https:\/\/shibaura-it.tokyo\/it-solution\/wp\/wp-content\/uploads\/2020\/10\/2020-10-10_19h15_44.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-494\" src=\"https:\/\/shibaura-it.tokyo\/it-solution\/wp\/wp-content\/uploads\/2020\/10\/2020-10-10_19h15_44-600x263.jpg\" alt=\"\" width=\"600\" height=\"263\" srcset=\"https:\/\/shibaura-it.tokyo\/it-solution\/wp\/wp-content\/uploads\/2020\/10\/2020-10-10_19h15_44-600x263.jpg 600w, https:\/\/shibaura-it.tokyo\/it-solution\/wp\/wp-content\/uploads\/2020\/10\/2020-10-10_19h15_44-768x337.jpg 768w, https:\/\/shibaura-it.tokyo\/it-solution\/wp\/wp-content\/uploads\/2020\/10\/2020-10-10_19h15_44.jpg 1024w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<p>GUI_Main.py\u3092\u7de8\u96c6\u3059\u308b\u3053\u3068\u3067\u3001GUI\u306e\u9aa8\u683c\u90e8\u5206\u306e\u6539\u5909\u304c\u53ef\u80fd\u3067\u3059\u3002<br \/>\n\u5916\u90e8\u306e\u30d1\u30c3\u30b1\u30fc\u30b8\u306b\u3088\u3063\u3066\u5b9f\u73fe\u3055\u308c\u3066\u3044\u308b\u6a5f\u80fd\u306e\u6539\u5909\u306b\u3064\u3044\u3066\u306f\u3001<br \/>\n\u6b21\u56de\u8aac\u660e\u3055\u305b\u3066\u3044\u305f\u3060\u304d\u307e\u3059\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>asammdf\u306e\u30ea\u30dd\u30b8\u30c8\u30ea\u306f\u65e5\u3005\u66f4\u65b0\u3055\u308c\u308b\u306e\u3068\u540c\u69d8\u306b\u3001asammdf&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":494,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,7],"tags":[],"_links":{"self":[{"href":"https:\/\/shibaura-it.tokyo\/it-solution\/wp-json\/wp\/v2\/posts\/491"}],"collection":[{"href":"https:\/\/shibaura-it.tokyo\/it-solution\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/shibaura-it.tokyo\/it-solution\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/shibaura-it.tokyo\/it-solution\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/shibaura-it.tokyo\/it-solution\/wp-json\/wp\/v2\/comments?post=491"}],"version-history":[{"count":1,"href":"https:\/\/shibaura-it.tokyo\/it-solution\/wp-json\/wp\/v2\/posts\/491\/revisions"}],"predecessor-version":[{"id":495,"href":"https:\/\/shibaura-it.tokyo\/it-solution\/wp-json\/wp\/v2\/posts\/491\/revisions\/495"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/shibaura-it.tokyo\/it-solution\/wp-json\/wp\/v2\/media\/494"}],"wp:attachment":[{"href":"https:\/\/shibaura-it.tokyo\/it-solution\/wp-json\/wp\/v2\/media?parent=491"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/shibaura-it.tokyo\/it-solution\/wp-json\/wp\/v2\/categories?post=491"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/shibaura-it.tokyo\/it-solution\/wp-json\/wp\/v2\/tags?post=491"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}