def __init__(self, model): """Initialize MNELAB main window. Parameters ---------- model : mnelab.model.Model instance The main window needs to connect to a model containing all data sets. This decouples the GUI from the data (model/view). """ super().__init__() self.model = model # data model self.setWindowTitle("MNELAB") # restore settings settings = read_settings() self.recent = settings["recent"] # list of recent files self.resize(settings["size"]) self.move(settings["pos"]) # remove None entries from self.recent self.recent = [recent for recent in self.recent if recent is not None] # trigger theme setting QIcon.setThemeSearchPaths([str(Path(__file__).parent / "icons")]) self.event(QEvent(QEvent.PaletteChange)) self.actions = {} # contains all actions # initialize menus file_menu = self.menuBar().addMenu("&File") icon = QIcon.fromTheme("open-file") self.actions["open_file"] = file_menu.addAction( icon, "&Open...", self.open_data, QKeySequence.Open) self.recent_menu = file_menu.addMenu("Open recent") self.recent_menu.aboutToShow.connect(self._update_recent_menu) self.recent_menu.triggered.connect(self._load_recent) if not self.recent: self.recent_menu.setEnabled(False) self.actions["close_file"] = file_menu.addAction( "&Close", self.model.remove_data, QKeySequence.Close) self.actions["close_all"] = file_menu.addAction( "Close all", self.close_all) file_menu.addSeparator() icon = QIcon.fromTheme("meta-info") self.actions["meta_info"] = file_menu.addAction( icon, "Show information...", self.meta_info) file_menu.addSeparator() self.actions["import_bads"] = file_menu.addAction( "Import bad channels...", lambda: self.import_file( model.import_bads, "Import bad channels", "*.csv")) self.actions["import_events"] = file_menu.addAction( "Import events...", lambda: self.import_file( model.import_events, "Import events", "*.csv")) self.actions["import_annotations"] = file_menu.addAction( "Import annotations...", lambda: self.import_file( model.import_annotations, "Import annotations", "*.csv")) self.actions["import_ica"] = file_menu.addAction( "Import &ICA...", lambda: self.open_file( model.import_ica, "Import ICA", "*.fif *.fif.gz")) file_menu.addSeparator() self.export_menu = file_menu.addMenu("Export data") for ext, description in writers.items(): action = "export_data" + ext.replace(".", "_") self.actions[action] = self.export_menu.addAction( f"{ext[1:].upper()} ({description[1]})...", partial(self.export_file, model.export_data, "Export data", "*" + ext)) self.actions["export_bads"] = file_menu.addAction( "Export &bad channels...", lambda: self.export_file( model.export_bads, "Export bad channels", "*.csv")) self.actions["export_events"] = file_menu.addAction( "Export &events...", lambda: self.export_file( model.export_events, "Export events", "*.csv")) self.actions["export_annotations"] = file_menu.addAction( "Export &annotations...", lambda: self.export_file( model.export_annotations, "Export annotations", "*.csv")) self.actions["export_ica"] = file_menu.addAction( "Export ICA...", lambda: self.export_file( model.export_ica, "Export ICA", "*.fif *.fif.gz")) file_menu.addSeparator() self.actions["xdf_chunks"] = file_menu.addAction( "Show XDF chunks...", self.xdf_chunks) file_menu.addSeparator() self.actions["quit"] = file_menu.addAction("&Quit", self.close, QKeySequence.Quit) edit_menu = self.menuBar().addMenu("&Edit") self.actions["pick_chans"] = edit_menu.addAction( "P&ick channels...", self.pick_channels) icon = QIcon.fromTheme("chan-props") self.actions["chan_props"] = edit_menu.addAction( icon, "Channel &properties...", self.channel_properties) self.actions["set_montage"] = edit_menu.addAction( "Set &montage...", self.set_montage) edit_menu.addSeparator() self.actions["set_ref"] = edit_menu.addAction("Set &reference...", self.set_reference) edit_menu.addSeparator() self.actions["annotations"] = edit_menu.addAction( "&Annotations...", self.edit_annotations) self.actions["events"] = edit_menu.addAction("&Events...", self.edit_events) edit_menu.addSeparator() self.actions["crop"] = edit_menu.addAction("&Crop data...", self.crop) self.actions["append_data"] = edit_menu.addAction( "Appen&d data...", self.append_data) plot_menu = self.menuBar().addMenu("&Plot") icon = QIcon.fromTheme("plot-data") self.actions["plot_data"] = plot_menu.addAction( icon, "&Data", self.plot_data) icon = QIcon.fromTheme("plot-psd") self.actions["plot_psd"] = plot_menu.addAction( icon, "&Power spectral density", self.plot_psd) icon = QIcon.fromTheme("plot-locations") self.actions["plot_locations"] = plot_menu.addAction( icon, "&Channel locations", self.plot_locations) self.actions["plot_erds"] = plot_menu.addAction( "&ERDS maps...", self.plot_erds) plot_menu.addSeparator() self.actions["plot_ica_components"] = plot_menu.addAction( "ICA &components...", self.plot_ica_components) self.actions["plot_ica_sources"] = plot_menu.addAction( "ICA &sources...", self.plot_ica_sources) tools_menu = self.menuBar().addMenu("&Tools") icon = QIcon.fromTheme("filter-data") self.actions["filter"] = tools_menu.addAction(icon, "&Filter data...", self.filter_data) icon = QIcon.fromTheme("find-events") self.actions["find_events"] = tools_menu.addAction( icon, "Find &events...", self.find_events) self.actions["events_from_annotations"] = tools_menu.addAction( "Create events from annotations", self.events_from_annotations) self.actions["annotations_from_events"] = tools_menu.addAction( "Create annotations from events", self.annotations_from_events) tools_menu.addSeparator() nirs_menu = tools_menu.addMenu("NIRS") self.actions["convert_od"] = nirs_menu.addAction( "Convert to &optical density", self.convert_od) self.actions["convert_bl"] = nirs_menu.addAction( "Convert to &haemoglobin", self.convert_bl) tools_menu.addSeparator() icon = QIcon.fromTheme("run-ica") self.actions["run_ica"] = tools_menu.addAction(icon, "Run &ICA...", self.run_ica) self.actions["apply_ica"] = tools_menu.addAction( "Apply &ICA", self.apply_ica) tools_menu.addSeparator() self.actions["interpolate_bads"] = tools_menu.addAction( "Interpolate bad channels...", self.interpolate_bads) tools_menu.addSeparator() icon = QIcon.fromTheme("epoch-data") self.actions["epoch_data"] = tools_menu.addAction( icon, "Create epochs...", self.epoch_data) view_menu = self.menuBar().addMenu("&View") self.actions["history"] = view_menu.addAction("&History...", self.show_history) self.actions["toolbar"] = view_menu.addAction("&Toolbar", self._toggle_toolbar) self.actions["toolbar"].setCheckable(True) self.actions["statusbar"] = view_menu.addAction( "&Statusbar", self._toggle_statusbar) self.actions["statusbar"].setCheckable(True) help_menu = self.menuBar().addMenu("&Help") self.actions["about"] = help_menu.addAction("&About", self.show_about) self.actions["about_qt"] = help_menu.addAction("About &Qt", self.show_about_qt) # actions that are always enabled self.always_enabled = [ "open_file", "about", "about_qt", "quit", "xdf_chunks", "toolbar", "statusbar" ] # set up toolbar self.toolbar = self.addToolBar("toolbar") self.toolbar.setObjectName("toolbar") self.toolbar.addAction(self.actions["open_file"]) self.toolbar.addAction(self.actions["meta_info"]) self.toolbar.addSeparator() self.toolbar.addAction(self.actions["chan_props"]) self.toolbar.addSeparator() self.toolbar.addAction(self.actions["plot_data"]) self.toolbar.addAction(self.actions["plot_psd"]) self.toolbar.addAction(self.actions["plot_locations"]) self.toolbar.addSeparator() self.toolbar.addAction(self.actions["filter"]) self.toolbar.addAction(self.actions["find_events"]) self.toolbar.addAction(self.actions["epoch_data"]) self.toolbar.addAction(self.actions["run_ica"]) self.toolbar.setMovable(False) self.setUnifiedTitleAndToolBarOnMac(True) if settings["toolbar"]: self.toolbar.show() self.actions["toolbar"].setChecked(True) else: self.toolbar.hide() self.actions["toolbar"].setChecked(False) # set up data model for sidebar (list of open files) self.names = QStringListModel() self.names.dataChanged.connect(self._update_names) splitter = QSplitter() self.sidebar = QListView() self.sidebar.setFrameStyle(QFrame.NoFrame) self.sidebar.setFocusPolicy(Qt.NoFocus) self.sidebar.setModel(self.names) self.sidebar.clicked.connect(self._update_data) splitter.addWidget(self.sidebar) self.infowidget = InfoWidget() splitter.addWidget(self.infowidget) width = splitter.size().width() splitter.setSizes((int(width * 0.3), int(width * 0.7))) self.setCentralWidget(splitter) self.status_label = QLabel() self.statusBar().addPermanentWidget(self.status_label) if settings["statusbar"]: self.statusBar().show() self.actions["statusbar"].setChecked(True) else: self.statusBar().hide() self.actions["statusbar"].setChecked(False) self.setAcceptDrops(True) self.data_changed()
def resource_path(path): if getattr(sys, 'frozen', False): basedir = sys._MEIPASS else: basedir = os.path.dirname(__file__) return os.path.join(basedir, path) if __name__ == '__main__': print(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'icons')) d = [] d.extend([os.path.join(d, '.icons') for d in get_xdr_data_home()]) d.extend([os.path.join(d, 'icons') for d in get_xdr_data_dirs()]) d.extend([resource_path('icons')]) QIcon.setThemeSearchPaths(d) QIcon.setThemeName('default') app = QApplication(sys.argv) app.setApplicationName(APPLICATION_NAME) app.setOrganizationName(ORGANIZATION_NAME) # QSettings.setDefaultFormat(QSettings.IniFormat) w = MainWindow() w.new_document() w.show() sys.exit(app.exec_())