Exemple #1
0
 def eventFilter(self, obj: QObject, event: QEvent):
     if obj.objectName() == "lineEdit":
         if event.type() == QEvent.DragEnter:
             new_method.lineEdit_dragEnterEvent(event)
             return True
         if event.type() == QEvent.Drop:
             new_method.lineEdit_dropEvent(self, event)
             return True
     return QObject.eventFilter(self, obj, event)
 def eventFilter(self, obj: QtWidgets.QComboBox, event: QEvent) -> bool:
     if event.type() == QEvent.Wheel and isinstance(obj,
                                                    QtWidgets.QComboBox):
         if obj.focusPolicy() == Qt.WheelFocus:
             event.accept()
             return False
         else:
             event.ignore()
             return True
     return super().eventFilter(obj, event)
Exemple #3
0
    def event(self, event: QEvent) -> bool:
        if event.type() == QEvent.ToolTip:
            offset = self.xy_to_offset(event.pos().x(), event.pos().y())
            if offset is None:
                QToolTip.hideText()
                return True
            self.signal_show_tooltip_at_offset.emit(offset, event.globalPos())
            return True

        return super().event(event)
 def eventFilter(self, obj: QObject, event: QEvent) -> bool:
     """Filter events for custom title bar."""
     if obj is self.ui.titleRightInfo and event.type(
     ) == QEvent.MouseButtonDblClick:
         # This was originally done with a delay of 250 but I didn't like it.
         # QTimer.singleShot(250, lambda: self.maximize_restore())
         self.maximize_restore()
     if obj is self.ui.titleRightInfo and event.type(
     ) == QEvent.MouseButtonPress:
         self.drag_pos = event.globalPos()
     if obj is self.ui.titleRightInfo and event.type() == QEvent.MouseMove:
         # Restore the window when it is moved in maximized state.
         if self.isMaximized():
             # TODO: When doing this, we also need to move the window so it's under the mouse cursor!
             self.maximize_restore()
         # Move the window to the new position.
         if event.buttons() == Qt.LeftButton:
             self.move(self.pos() + event.globalPos() - self.drag_pos)
             self.drag_pos = event.globalPos()
             return True
     if obj is self.ui.titleRightInfo and event.type(
     ) == QEvent.MouseButtonRelease:
         # Todo: Check if we should move it to the last received position.
         self.drag_pos = None
     if obj is self and event.type() == QEvent.Resize:
         self.resize_grips()
     return False
Exemple #5
0
 def changeEvent(self, event: QtCore.QEvent):
     if event.type() == QtCore.QEvent.StyleChange:
         setup_matplotlib()
         self._figure.clear()
         self.main_layout.removeWidget(self._canvas)
         self._canvas.setVisible(False)
         self._figure = plt.figure(figsize=self._figure.get_size_inches())
         self._canvas = FigureCanvas(self._figure)
         self._toolbar = NavigationToolbar(self._canvas, self)
         self.main_layout.addWidget(self._canvas, 0, 0)
         self.update_chart()
     elif event.type() == QtCore.QEvent.LanguageChange:
         self.retranslate()
Exemple #6
0
 def eventFilter(self, watched: QtCore.QObject,
                 event: QtCore.QEvent) -> bool:
     if event.type() == QtCore.QEvent.Type.KeyPress:
         if event.key() == Qt.Key_M:
             if self.value() == 0:
                 self.setValue(self.tmpValue)
             else:
                 self.tmpValue = self.value()
                 self.setValue(0)
             return True
         elif event.key() == Qt.Key_Escape:
             self.clearFocus()
             return True
     return False
Exemple #7
0
 def recognize(self, state: QGesture, watched,
               event: QEvent) -> QGestureRecognizer.Result:
     if event.type() == QEvent.TouchBegin:
         touch_event: QTouchEvent = event
         if len(touch_event.touchPoints()) == 1:
             state.press = touch_event.touchPoints()[0]
             state.pos = state.press
             return QGestureRecognizer.MayBeGesture
     elif event.type() == QEvent.TouchUpdate:
         touch_event: QTouchEvent = event
         state.last = state.pos
         state.pos = touch_event.touchPoints()[0]
         return QGestureRecognizer.TriggerGesture
     return QGestureRecognizer.Ignore
 def change_event(self, event: QtCore.QEvent) -> None:
     """Update the tooltip's colors when the palette changes."""
     if event.type() == QtCore.QEvent.Type.PaletteChange:
         self._value_spinbox.style_sheet = _SPINBOX_BORDER_STYLESHEET.format(
             border_color=self.palette.window().color().darker(140).name()
         )
     super().change_event(event)
Exemple #9
0
 def eventFilter(self, watched: QtCore.QObject,
                 event: QtCore.QEvent) -> bool:
     if (event.type() == QtCore.QEvent.Resize):
         if not self.pix.isNull():
             pixmap = self.pix.scaled(
                 self.width(), self.height(),
                 QtCore.Qt.AspectRatioMode.KeepAspectRatio,
                 QtCore.Qt.TransformationMode.SmoothTransformation)
             if pixmap.width() != self.width() or pixmap.height(
             ) != self.height():
                 self.ResizeSignal.emit(0)
     return super().eventFilter(watched, event)
Exemple #10
0
 def eventFilter(self, watched: QtCore.QObject,
                 event: QtCore.QEvent) -> bool:
     # print("event received")
     if event.type() == QtCore.QEvent.Gesture:
         # print("Tap and hold detected")
         self.held = True
         # self.bgColor = QtGui.QColor("red")
         # self.ignoreFirstClick = 0
         self.setChecked(True)
         # self.pressedColor = QtGui.QColor("red")
         self.setDown(False)
         self.warnStateHeld()
         self.repaint()
         return True
     return False
Exemple #11
0
    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()
Exemple #12
0
 def change_event(self, event: QtCore.QEvent) -> None:
     """Retranslate the GUI when a language change occurs."""
     if event.type() == QtCore.QEvent.LanguageChange:
         self.retranslate()
Exemple #13
0
 def changeEvent(self, event: QtCore.QEvent):
     if event.type() == QtCore.QEvent.LanguageChange:
         self.retranslate()
 def change_event(self, event: QtCore.QEvent) -> None:
     """Update the fade images if the palette changed."""
     if event.type() == QtCore.QEvent.PaletteChange:
         self._fade_in_image, self._fade_out_image = self._create_fade_images(
         )
     super().change_event(event)
Exemple #15
0
 def contextMenuEvent(self, event: QEvent) -> None:
     self._copy_table_action.setEnabled(bool(self.rowCount()))
     self._copy_row_action.setEnabled(bool(self.selectedItems()))
     self._context_menu.exec_(self.viewport().mapToGlobal(event.pos()))
    def change_event(self, event: QtCore.QEvent) -> None:
        """Update the tooltip's colors when the palette changes."""
        if event.type() == QtCore.QEvent.Type.PaletteChange:
            self.refresh_button.icon = self.get_refresh_icon(is_dark())

        super().change_event(event)