def contextMenuEvent(self, event):
     super().contextMenuEvent(event)
     term = self.itemAt(event.pos()).term
     self._currMenu = QMenu()
     self._currAction = self._currMenu.addAction("View term on AmiGO website")
     self._currAction.triggered.connect(lambda: self.BrowserAction(term))
     self._currMenu.popup(event.globalPos())
Esempio n. 2
0
 def __create_popup_menu(self):
     if not self._popup_menu:
         self.form.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
         self.form.customContextMenuRequested.connect(self._open_popup_menu)
         self._popup_menu = QMenu(self.parent)
         self._popup_menu.aboutToShow.connect(
             self.about_to_show_contextmenu_event)
Esempio n. 3
0
    def menu_button(self, main_action_id, ids, widget):
        '''
            Creates an :obj:`.OWButton` with a popup-menu and adds it to the parent ``widget``.
        '''
        id, _, attr_name, attr_value, callback, icon_name = self._expand_id(main_action_id)
        b = OWButton(parent=widget)
        m = QMenu(b)
        b.setMenu(m)
        b._actions = {}

        m.triggered[QAction].connect(b.setDefaultAction)

        if main_action_id:
            main_action = OWAction(self._plot, icon_name, attr_name, attr_value, callback,
                                   parent=b)
            m.triggered.connect(main_action.trigger)

        for id in ids:
            id, _, attr_name, attr_value, callback, icon_name = self._expand_id(id)
            a = OWAction(self._plot, icon_name, attr_name, attr_value, callback, parent=m)
            m.addAction(a)
            b._actions[id] = a

        if m.actions():
            b.setDefaultAction(m.actions()[0])
        elif main_action_id:
            b.setDefaultAction(main_action)


        b.setPopupMode(QToolButton.MenuButtonPopup)
        b.setMinimumSize(40, 30)
        return b
class GOTreeWidget(QTreeWidget):
    def contextMenuEvent(self, event):
        super().contextMenuEvent(event)
        term = self.itemAt(event.pos()).term
        self._currMenu = QMenu()
        self._currAction = self._currMenu.addAction("View term on AmiGO website")
        self._currAction.triggered.connect(lambda: self.BrowserAction(term))
        self._currMenu.popup(event.globalPos())

    def BrowserAction(self, term):
        if isinstance(term, go.Term):
            term = term.id
        webbrowser.open("http://amigo.geneontology.org/cgi-bin/amigo/term-details.cgi?term="+term)
class GOTreeWidget(QTreeWidget):
    def contextMenuEvent(self, event):
        super().contextMenuEvent(event)
        term = self.itemAt(event.pos()).term
        self._currMenu = QMenu()
        self._currAction = self._currMenu.addAction("View term on AmiGO website")
        self._currAction.triggered.connect(lambda: self.BrowserAction(term))
        self._currMenu.popup(event.globalPos())

    def BrowserAction(self, term):
        if isinstance(term, go.Term):
            term = term.id
        webbrowser.open("http://amigo.geneontology.org/cgi-bin/amigo/term-details.cgi?term="+term)
    def contextMenuEvent(self, event):
        self._menu = menu = QMenu()
        action = menu.addAction("View this pathway on KEGG website")
        address = "http://www.kegg.jp/kegg-bin/show_pathway?%s%s" % (self.pathway.org, self.pathway.number)

        action.triggered.connect(partial(webbrowser.open, address))
        menu.popup(event.screenPos())
 def contextMenuEvent(self, event):
     super().contextMenuEvent(event)
     term = self.itemAt(event.pos()).term
     self._currMenu = QMenu()
     self._currAction = self._currMenu.addAction("View term on AmiGO website")
     self._currAction.triggered.connect(lambda: self.BrowserAction(term))
     self._currMenu.popup(event.globalPos())
Esempio n. 8
0
    def show_column_chooser(self, pos):
        # pylint doesn't know that self.shown_scores is a set, not a Setting
        # pylint: disable=unsupported-membership-test
        def update(col_name, checked):
            if checked:
                self.shown_scores.add(col_name)
            else:
                self.shown_scores.remove(col_name)
            self._update_shown_columns()

        menu = QMenu()
        header = self.view.horizontalHeader()
        for col_name in self._column_names():
            action = menu.addAction(col_name)
            action.setCheckable(True)
            action.setChecked(col_name in self.shown_scores)
            action.triggered.connect(partial(update, col_name))
        menu.exec(header.mapToGlobal(pos))
class GOTreeWidget(QTreeWidget):
    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self._currMenu = QMenu()
        self._currAction = self._currMenu.addAction(
            "View term on AmiGO website")

    def contextMenuEvent(self, event):
        super().contextMenuEvent(event)

        def browser_action(_term):
            if isinstance(_term, go.Term):
                _term = _term.id
            webbrowser.open(
                f'http://amigo.geneontology.org/amigo/term/{_term}')

        term = self.itemAt(event.pos()).term
        self._currAction.triggered.connect(lambda: browser_action(term))
        self._currMenu.popup(event.globalPos())
Esempio n. 10
0
    def contextMenuEvent(self, event):
        if event.modifiers() & Qt.AltModifier:
            menu = QMenu(event.widget())
            menu.setAttribute(Qt.WA_DeleteOnClose)
            formatmenu = menu.addMenu("Render as")
            group = QActionGroup(self, exclusive=True)

            def makeaction(text, parent, data=None, **kwargs):
                action = QAction(text, parent, **kwargs)
                if data is not None:
                    action.setData(data)
                return action

            formatactions = [
                makeaction(
                    "Plain Text",
                    group,
                    checkable=True,
                    toolTip=self.tr("Render contents as plain text"),
                    data="text/plain",
                ),
                makeaction(
                    "HTML",
                    group,
                    checkable=True,
                    toolTip=self.tr("Render contents as HTML"),
                    data="text/html",
                ),
                makeaction(
                    "RST",
                    group,
                    checkable=True,
                    toolTip=self.tr("Render contents as RST " "(reStructuredText)"),
                    data="text/rst",
                ),
                makeaction(
                    "Markdown",
                    group,
                    checkable=True,
                    toolTip=self.tr("Render contents as Markdown"),
                    data="text/markdown",
                ),
            ]
            for action in formatactions:
                action.setChecked(action.data() == self.__contentType.lower())
                formatmenu.addAction(action)

            def ontriggered(action):
                mimetype = action.data()
                content = self.content()
                self.setContent(content, mimetype)
                self.editingFinished.emit()

            menu.triggered.connect(ontriggered)
            menu.popup(event.screenPos())
            event.accept()
        else:
            event.ignore()
Esempio n. 11
0
    def show_column_chooser(self, pos):
        # pylint doesn't know that self.shown_scores is a set, not a Setting
        # pylint: disable=unsupported-membership-test
        def update(col_name, checked):
            if checked:
                self.shown_scores.add(col_name)
            else:
                self.shown_scores.remove(col_name)
            self._update_shown_columns()

        menu = QMenu()
        model = self.result_model
        header = self.view.horizontalHeader()
        for section in range(1, model.columnCount()):
            col_name = model.horizontalHeaderItem(section).data(Qt.DisplayRole)
            action = menu.addAction(col_name)
            action.setCheckable(True)
            action.setChecked(col_name in self.shown_scores)
            action.triggered.connect(partial(update, col_name))
        menu.exec(header.mapToGlobal(pos))
Esempio n. 12
0
    def show_column_chooser(self, pos):
        # pylint doesn't know that self.shown_scores is a set, not a Setting
        # pylint: disable=unsupported-membership-test
        def update(col_name, checked):
            if checked:
                self.shown_scores.add(col_name)
            else:
                self.shown_scores.remove(col_name)
            self._update_shown_columns()

        menu = QMenu()
        model = self.result_model
        header = self.view.horizontalHeader()
        for section in range(1, model.columnCount()):
            col_name = model.horizontalHeaderItem(section).data(Qt.DisplayRole)
            action = menu.addAction(col_name)
            action.setCheckable(True)
            action.setChecked(col_name in self.shown_scores)
            action.triggered.connect(partial(update, col_name))
        menu.exec(header.mapToGlobal(pos))
Esempio n. 13
0
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            if self.__popuptext:
                popup = QMenu(self)
                label = QLabel(
                    self, textInteractionFlags=Qt.TextBrowserInteraction,
                    openExternalLinks=self.__openExternalLinks,
                )
                label.setText(self.__styled(self.__defaultStyleSheet,
                                            self.__popuptext))

                label.linkActivated.connect(self.linkActivated)
                label.linkHovered.connect(self.linkHovered)
                action = QWidgetAction(popup)
                action.setDefaultWidget(label)
                popup.addAction(action)
                popup.popup(event.globalPos(), action)
                event.accept()
            return
        else:
            super().mousePressEvent(event)
Esempio n. 14
0
    def add_popup_submenu(self, label, submenu=None):
        """
        It returns a new sub popup menu. If submenu is open the menu is added to the main popup menu.

        :param str label: Label of the option  
        :param QMenu submenu: Parent submenu to which the option should be added. If no value is set, then the option will be added to the main popup menu.  
        """
        self.__create_popup_menu()
        menu = submenu if submenu else self._popup_menu
        submenu = QMenu(label, menu)
        menu.addMenu(submenu)
        return submenu
Esempio n. 15
0
 def rebuild_menu(self):
     # Terrible way to clear hotkey shortcuts set to actions because Qt can not do that.
     self._menu = QMenu()
     self._action_screen = self._menu.addAction(self.tr('Make Screenshot'))
     self._action_screen.triggered.connect(self.capture_screen)
     self._action_clip = self._menu.addAction(self.tr('Share Clipboard'))
     self._action_clip.triggered.connect(self.share_clipboard)
     self._menu.addSeparator()
     self._menu.addAction(self.tr('Settings')).triggered.connect(self.show_settings)
     self._menu.addSeparator()
     self._menu.addAction(self.tr('Exit')).triggered.connect(lambda: QApplication.exit(0))
     self._tray.setContextMenu(self._menu)
Esempio n. 16
0
    def menu_button(self, main_action_id, ids, widget):
        '''
            Creates an :obj:`.OWButton` with a popup-menu and adds it to the parent ``widget``.
        '''
        id, _, attr_name, attr_value, callback, icon_name = self._expand_id(main_action_id)
        b = OWButton(parent=widget)
        m = QMenu(b)
        b.setMenu(m)
        b._actions = {}

        m.triggered[QAction].connect(b.setDefaultAction)

        if main_action_id:
            main_action = OWAction(self._plot, icon_name, attr_name, attr_value, callback,
                                   parent=b)
            m.triggered.connect(main_action.trigger)

        for id in ids:
            id, _, attr_name, attr_value, callback, icon_name = self._expand_id(id)
            a = OWAction(self._plot, icon_name, attr_name, attr_value, callback, parent=m)
            m.addAction(a)
            b._actions[id] = a

        if m.actions():
            b.setDefaultAction(m.actions()[0])
        elif main_action_id:
            b.setDefaultAction(main_action)


        b.setPopupMode(QToolButton.MenuButtonPopup)
        b.setMinimumSize(40, 30)
        return b
Esempio n. 17
0
    def test_lineedit(self):
        """test LineEdit
        """
        line = LineEdit()
        line.show()

        action1 = QAction(QIcon(line.style().standardPixmap(
                                    QStyle.SP_ArrowBack)
                                ),
                          "Search", line)
        menu = QMenu()
        menu.addAction("Regex")
        menu.addAction("Wildcard")
        action1.setMenu(menu)

        line.setAction(action1, LineEdit.LeftPosition)
        self.assertIs(line.actionAt(LineEdit.LeftPosition), action1)
        self.assertTrue(line.button(LineEdit.LeftPosition) is not None)
        self.assertTrue(line.button(LineEdit.RightPosition) is None)

        with self.assertRaises(ValueError):
            line.removeActionAt(100)

        line.removeActionAt(LineEdit.LeftPosition)
        self.assertIs(line.actionAt(LineEdit.LeftPosition), None)

        line.setAction(action1, LineEdit.LeftPosition)

        action2 = QAction(QIcon(line.style().standardPixmap(
                                        QStyle.SP_TitleBarCloseButton)),
                          "Delete", line)
        line.setAction(action2, LineEdit.RightPosition)

        line.setPlaceholderText("Search")
        self.assertEqual(line.placeholderText(), "Search")

        b = line.button(LineEdit.RightPosition)
        b.setFlat(False)
        self.app.exec_()
Esempio n. 18
0
 def __menu_requested(self, point: QPoint):
     index = self.view.indexAt(point)
     model: QSortFilterProxyModel = index.model()
     source_index = model.mapToSource(index)
     menu = QMenu(self)
     for action in self._create_actions(source_index):
         menu.addAction(action)
     menu.popup(self.view.viewport().mapToGlobal(point))
Esempio n. 19
0
 def contextMenuEvent(self, event):
     wrapped = []
     menu = QMenu(self.parentWidget())
     for text, param in (
             ("Promote", 1),
             ("Demote", -1)):
         wrapper = functools.partial(self.promote, param)
         wrapped.append(wrapper)
         menu.addAction(text, wrapper)
     menu.exec_(event.screenPos())
Esempio n. 20
0
 def addAction(menu: QMenu,
               text: str,
               slot: Callable[[], Any],
               shortcut: Optional[QKeySequence.StandardKey] = None,
               enabled=True,
               objectName="",
               icon="") -> QAction:
     ac = menu.addAction(text)
     ac.triggered.connect(slot)
     ac.setEnabled(enabled)
     if shortcut:
         ac.setShortcut(shortcut)
     if objectName:
         ac.setObjectName(objectName)
     if icon:
         setActionIcon(ac, icon)
     return ac
Esempio n. 21
0
    def _setup_library_box(self):
        self.library_view = QListView(
            editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed,
            minimumWidth=200,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Expanding),
        )
        self.library_view.setItemDelegate(WordListItemDelegate(self))
        self.library_view.setModel(self.library_model)
        self.library_view.selectionModel().selectionChanged.connect(
            self.__on_library_selection_changed)

        self.__library_box.layout().setSpacing(1)
        self.__library_box.layout().addWidget(self.library_view)

        actions_widget = ModelActionsWidget()
        actions_widget.layout().setSpacing(1)

        action = QAction("+", self)
        action.setToolTip("Add a new word list to the library")
        action.triggered.connect(self.__on_add_word_list)
        actions_widget.addAction(action)

        action = QAction("\N{MINUS SIGN}", self)
        action.setToolTip("Remove word list from library")
        action.triggered.connect(self.__on_remove_word_list)
        actions_widget.addAction(action)

        action = QAction("Update", self)
        action.setToolTip("Save changes in the editor to library")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.triggered.connect(self.__on_update_word_list)
        actions_widget.addAction(action)

        gui.rubber(actions_widget.layout())

        action = QAction("More", self, toolTip="More actions")

        new_from_file = QAction("Import Words from File", self)
        new_from_file.triggered.connect(self.__on_import_word_list)

        save_to_file = QAction("Save Words to File", self)
        save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs))
        save_to_file.triggered.connect(self.__on_save_word_list)

        menu = QMenu(actions_widget)
        menu.addAction(new_from_file)
        menu.addAction(save_to_file)
        action.setMenu(menu)
        button = actions_widget.addAction(action)
        button.setPopupMode(QToolButton.InstantPopup)
        self.__library_box.layout().addWidget(actions_widget)
Esempio n. 22
0
 def mousePressEvent(self, event):
     if event.button() == Qt.LeftButton:
         if self.__popuptext:
             popup = QMenu(self)
             label = QLabel(self,
                            textInteractionFlags=Qt.TextBrowserInteraction,
                            openExternalLinks=self.__openExternalLinks,
                            text=self.__popuptext)
             label.linkActivated.connect(self.linkActivated)
             label.linkHovered.connect(self.linkHovered)
             action = QWidgetAction(popup)
             action.setDefaultWidget(label)
             popup.addAction(action)
             popup.popup(event.globalPos(), action)
             event.accept()
         return
     else:
         super().mousePressEvent(event)
Esempio n. 23
0
    def contextMenuEvent(self, event):
        if event.modifiers() & Qt.AltModifier:
            menu = QMenu(event.widget())
            menu.setAttribute(Qt.WA_DeleteOnClose)
            formatmenu = menu.addMenu("Render as")
            group = QActionGroup(self, exclusive=True)

            def makeaction(text, parent, data=None, **kwargs):
                action = QAction(text, parent, **kwargs)
                if data is not None:
                    action.setData(data)
                return action

            formatactions = [
                makeaction("Plain Text", group, checkable=True,
                           toolTip=self.tr("Render contents as plain text"),
                           data="text/plain"),
                makeaction("HTML", group, checkable=True,
                           toolTip=self.tr("Render contents as HTML"),
                           data="text/html"),
                makeaction("RST", group, checkable=True,
                           toolTip=self.tr("Render contents as RST "
                                           "(reStructuredText)"),
                           data="text/rst"),
                makeaction("Markdown", group, checkable=True,
                           toolTip=self.tr("Render contents as Markdown"),
                           data="text/markdown")
            ]
            for action in formatactions:
                action.setChecked(action.data() == self.__contentType.lower())
                formatmenu.addAction(action)

            def ontriggered(action):
                mimetype = action.data()
                content = self.content()
                self.setContent(content, mimetype)
                self.editingFinished.emit()

            menu.triggered.connect(ontriggered)
            menu.popup(event.screenPos())
            event.accept()
        else:
            event.ignore()
    def test_lineedit(self):
        """test LineEdit
        """
        line = LineEdit()
        line.show()

        action1 = QAction(
            QIcon(line.style().standardPixmap(QStyle.SP_ArrowBack)), "Search",
            line)
        menu = QMenu()
        menu.addAction("Regex")
        menu.addAction("Wildcard")
        action1.setMenu(menu)

        line.setAction(action1, LineEdit.LeftPosition)
        self.assertIs(line.actionAt(LineEdit.LeftPosition), action1)
        self.assertTrue(line.button(LineEdit.LeftPosition) is not None)
        self.assertTrue(line.button(LineEdit.RightPosition) is None)

        with self.assertRaises(ValueError):
            line.removeActionAt(100)

        line.removeActionAt(LineEdit.LeftPosition)
        self.assertIs(line.actionAt(LineEdit.LeftPosition), None)

        line.setAction(action1, LineEdit.LeftPosition)

        action2 = QAction(
            QIcon(line.style().standardPixmap(QStyle.SP_TitleBarCloseButton)),
            "Delete",
            line,
        )
        line.setAction(action2, LineEdit.RightPosition)

        line.setPlaceholderText("Search")
        self.assertEqual(line.placeholderText(), "Search")

        b = line.button(LineEdit.RightPosition)
        b.setFlat(False)
        self.app.exec_()
Esempio n. 25
0
    def __init__(self):
        super().__init__()

        for name in self.signal_names:
            setattr(self, name, {})

        for s in self.libraryListSource:
            s.flags = 0

        self._cachedDocuments = {}

        self.infoBox = gui.vBox(self.controlArea, 'Info')
        gui.label(
            self.infoBox, self,
            "<p>Execute python script.</p><p>Input variables:<ul><li> " +
            "<li>".join(map("in_{0}, in_{0}s".format, self.signal_names)) +
            "</ul></p><p>Output variables:<ul><li>" +
            "<li>".join(map("out_{0}".format, self.signal_names)) +
            "</ul></p>"
        )

        self.libraryList = itemmodels.PyListModel(
            [], self,
            flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)

        self.libraryList.wrap(self.libraryListSource)

        self.controlBox = gui.vBox(self.controlArea, 'Library')
        self.controlBox.layout().setSpacing(1)

        self.libraryView = QListView(
            editTriggers=QListView.DoubleClicked |
            QListView.EditKeyPressed,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored,
                                   QSizePolicy.Preferred)
        )
        self.libraryView.setItemDelegate(ScriptItemDelegate(self))
        self.libraryView.setModel(self.libraryList)

        self.libraryView.selectionModel().selectionChanged.connect(
            self.onSelectedScriptChanged
        )
        self.controlBox.layout().addWidget(self.libraryView)

        w = itemmodels.ModelActionsWidget()

        self.addNewScriptAction = action = QAction("+", self)
        action.setToolTip("Add a new script to the library")
        action.triggered.connect(self.onAddScript)
        w.addAction(action)

        action = QAction(unicodedata.lookup("MINUS SIGN"), self)
        action.setToolTip("Remove script from library")
        action.triggered.connect(self.onRemoveScript)
        w.addAction(action)

        action = QAction("Update", self)
        action.setToolTip("Save changes in the editor to library")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.triggered.connect(self.commitChangesToLibrary)
        w.addAction(action)

        action = QAction("More", self, toolTip="More actions")

        new_from_file = QAction("Import Script from File", self)
        save_to_file = QAction("Save Selected Script to File", self)
        restore_saved = QAction("Undo Changes to Selected Script", self)
        save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs))

        new_from_file.triggered.connect(self.onAddScriptFromFile)
        save_to_file.triggered.connect(self.saveScript)
        restore_saved.triggered.connect(self.restoreSaved)

        menu = QMenu(w)
        menu.addAction(new_from_file)
        menu.addAction(save_to_file)
        menu.addAction(restore_saved)
        action.setMenu(menu)
        button = w.addAction(action)
        button.setPopupMode(QToolButton.InstantPopup)

        w.layout().setSpacing(1)

        self.controlBox.layout().addWidget(w)

        self.execute_button = gui.button(self.controlArea, self, 'Run', callback=self.commit)

        self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea)
        self.mainArea.layout().addWidget(self.splitCanvas)

        self.defaultFont = defaultFont = \
            "Monaco" if sys.platform == "darwin" else "Courier"

        self.textBox = gui.vBox(self, 'Python Script')
        self.splitCanvas.addWidget(self.textBox)
        self.text = PythonScriptEditor(self)
        self.textBox.layout().addWidget(self.text)

        self.textBox.setAlignment(Qt.AlignVCenter)
        self.text.setTabStopWidth(4)

        self.text.modificationChanged[bool].connect(self.onModificationChanged)

        self.saveAction = action = QAction("&Save", self.text)
        action.setToolTip("Save script to file")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.setShortcutContext(Qt.WidgetWithChildrenShortcut)
        action.triggered.connect(self.saveScript)

        self.consoleBox = gui.vBox(self, 'Console')
        self.splitCanvas.addWidget(self.consoleBox)
        self.console = PythonConsole({}, self)
        self.consoleBox.layout().addWidget(self.console)
        self.console.document().setDefaultFont(QFont(defaultFont))
        self.consoleBox.setAlignment(Qt.AlignBottom)
        self.console.setTabStopWidth(4)

        select_row(self.libraryView, self.currentScriptIndex)

        self.restoreScriptText()

        self.splitCanvas.setSizes([2, 1])
        if self.splitterState is not None:
            self.splitCanvas.restoreState(QByteArray(self.splitterState))

        self.splitCanvas.splitterMoved[int, int].connect(self.onSpliterMoved)
        self.controlArea.layout().addStretch(1)
        self.resize(800, 600)
Esempio n. 26
0
    def __init__(self):
        super().__init__()
        self.data = None
        self.editors = {}

        box = gui.vBox(self.controlArea, "变量定义")

        toplayout = QHBoxLayout()
        toplayout.setContentsMargins(0, 0, 0, 0)
        box.layout().addLayout(toplayout)

        self.editorstack = QStackedWidget(sizePolicy=QSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding))

        for descclass, editorclass in self.EDITORS:
            editor = editorclass()
            editor.featureChanged.connect(self._on_modified)
            self.editors[descclass] = editor
            self.editorstack.addWidget(editor)

        self.editorstack.setEnabled(False)

        buttonlayout = QVBoxLayout(spacing=10)
        buttonlayout.setContentsMargins(0, 0, 0, 0)

        self.addbutton = QPushButton("新建",
                                     toolTip="Create a new variable",
                                     minimumWidth=120,
                                     shortcut=QKeySequence.New)

        def unique_name(fmt, reserved):
            candidates = (fmt.format(i) for i in count(1))
            return next(c for c in candidates if c not in reserved)

        def generate_newname(fmt):
            return unique_name(fmt, self.reserved_names())

        menu = QMenu(self.addbutton)
        cont = menu.addAction("数值数据")
        cont.triggered.connect(lambda: self.addFeature(
            ContinuousDescriptor(generate_newname("X{}"), "", 3)))
        disc = menu.addAction("分类数据")
        disc.triggered.connect(lambda: self.addFeature(
            DiscreteDescriptor(generate_newname("D{}"), "", (), False)))
        string = menu.addAction("文本")
        string.triggered.connect(lambda: self.addFeature(
            StringDescriptor(generate_newname("S{}"), "")))
        datetime = menu.addAction("日期/时间")
        datetime.triggered.connect(lambda: self.addFeature(
            DateTimeDescriptor(generate_newname("T{}"), "")))

        menu.addSeparator()
        self.duplicateaction = menu.addAction("复制选中变量")
        self.duplicateaction.triggered.connect(self.duplicateFeature)
        self.duplicateaction.setEnabled(False)
        self.addbutton.setMenu(menu)

        self.removebutton = QPushButton("删除",
                                        toolTip="删除选中变量",
                                        minimumWidth=120,
                                        shortcut=QKeySequence.Delete)
        self.removebutton.clicked.connect(self.removeSelectedFeature)

        buttonlayout.addWidget(self.addbutton)
        buttonlayout.addWidget(self.removebutton)
        buttonlayout.addStretch(10)

        toplayout.addLayout(buttonlayout, 0)
        toplayout.addWidget(self.editorstack, 10)

        # Layout for the list view
        layout = QVBoxLayout(spacing=1, margin=0)
        self.featuremodel = DescriptorModel(parent=self)

        self.featureview = QListView(minimumWidth=200,
                                     minimumHeight=50,
                                     sizePolicy=QSizePolicy(
                                         QSizePolicy.Minimum,
                                         QSizePolicy.MinimumExpanding))

        self.featureview.setItemDelegate(FeatureItemDelegate(self))
        self.featureview.setModel(self.featuremodel)
        self.featureview.selectionModel().selectionChanged.connect(
            self._on_selectedVariableChanged)

        layout.addWidget(self.featureview)

        box.layout().addLayout(layout, 1)

        self.fix_button = gui.button(self.buttonsArea,
                                     self,
                                     "Upgrade Expressions",
                                     callback=self.fix_expressions)
        self.fix_button.setHidden(True)
        gui.button(self.buttonsArea,
                   self,
                   "Send",
                   callback=self.apply,
                   default=True)
Esempio n. 27
0
class ControlBase(object):
    """
    All the Controls inherit from this Control, therefore you can find its functions and properties in all the other controls listed below.

    """

    def __init__(self, *args, **kwargs):
        """
        :param str label: Control label. Default = ''.
        :param str helptext: Text shown when the mouse is over the control. Default = None.
        :param str default: Initial value of the control. Default = None.

        :param bool visible: Flag to set the control visible or hidden. Default = True.
        :param bool enabled: Flag to set the control enabled or Disabled. Default = True.
        :param bool readonly: Flag to set the control readonly. Default = False.
        :param function changed_event: Function to call whenever the control value is updated. Default = None.  

        """

        self._form       = None  # Qt widget
        self._parent     = None  # Parent window
        self._popup_menu = None

        self._help          = kwargs.get('helptext', None)
        self._value         = kwargs.get('default',  None)
        self._label         = kwargs.get('label', args[0] if len(args)>0 else '')
        self._style         = kwargs.get('style', None)

        self.init_form()

        self.changed_event  = kwargs.get('changed_event', self.changed_event)
        self.enabled        = kwargs.get('enabled', True)
        self.readonly       = kwargs.get('readonly', False)
        if not kwargs.get('visible', True):  self.hide()


    def __repr__(self): return str(self._value)

    ##########################################################################
    ############ Funcions ####################################################
    ##########################################################################

    def init_form(self):
        """
        Load the control UI and initiate all the events.
        """     
        if self.help: self.form.setToolTip(self.help)

        if self._style: self.form.setStyleSheet(self._style)
   


    def load_form(self, data, path=None):
        """
        Loads the value of the control.

        :param dict data: It is a dictionary with the required information to load the control. 
        :param str path: Optional parameter that can be used to save the data.  
        """
        if 'value' in data:
            self.value = data['value']

    def save_form(self, data, path=None):
        """
        Save a value of the control to a dictionary.  

        :param dict data: Dictionary where the control value should be saved.  
        :param str path: Optional parameter that can be used to load the data.  
        """
        data['value'] = self.value
        return data

    def show(self):
        """
        Show the control
        """
        if self.form is None:
            return
        elif self.form==self:
            super(ControlBase,self).show()
        else:
            self.form.show()

    def hide(self):
        """
        Hide the control
        """
        if self.form is None:
            return
        elif self.form==self:
            super(ControlBase,self).hide()
        else:
            self.form.hide()


    def __create_popup_menu(self):
        if not self._popup_menu:
            self.form.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
            self.form.customContextMenuRequested.connect(self._open_popup_menu)
            self._popup_menu = QMenu(self.parent)
            self._popup_menu.aboutToShow.connect( self.about_to_show_contextmenu_event)

    def add_popup_submenu(self, label, submenu=None):
        """
        It returns a new sub popup menu. If submenu is open the menu is added to the main popup menu.

        :param str label: Label of the option  
        :param QMenu submenu: Parent submenu to which the option should be added. If no value is set, then the option will be added to the main popup menu.  
        """
        self.__create_popup_menu()
        menu = submenu if submenu else self._popup_menu
        submenu = QMenu(label, menu)
        menu.addMenu(submenu)
        return submenu

    def add_popup_menu_option(self, label, function_action=None, key=None, icon=None, menu=None):
        """
        Add an option to the Control popup menu.  

        :param str label: Label of the option  
        :param function function_action: The function that should be executed when the menu is selected.  
        :param str key: Short key.  
        :param QIcon or str icon: Icon.  
        :param QMenu submenu: Parent submenu to which the option should be added. If no value is set, then the option will be added to the main popup menu.  
        
        .. code:: python

            control.add_popup_menu_option('option 0', function_action=self._do_something)
            submenu1 = control.add_popup_submenu('menu 1')
            submenu2 = control.add_popup_submenu('menu 2', submenu=submenu1)
            control.add_popup_menu_option('option 1', function_action=self._do_something, key='Control+Q', submenu=submenu2)
        """
        self.__create_popup_menu()

        menu = menu if menu else self._popup_menu

        if label == "-":
            return menu.addSeparator()
        else:
            action = QAction(label, self.form)
            if icon is not None:
                action.setIconVisibleInMenu(True)
                action.setIcon(icon if isinstance(icon, QIcon) else QIcon(icon) )
            if key != None:
                action.setShortcut(QKeySequence(key))
            if function_action:
                action.triggered.connect(function_action)
                menu.addAction(action)
            return action


    ##########################################################################
    ############ Events ######################################################
    ##########################################################################

    def changed_event(self):
        """
        Function called when ever the Control value is changed. The event function should return True if the data was saved with success.

        """
        return True

    def about_to_show_contextmenu_event(self):
        """
        Function called before the Control popup menu is opened.
        """
        pass

    def _open_popup_menu(self, position):
        if self._popup_menu:
            self._popup_menu.exec_(self.form.mapToGlobal(position))

    ##########################################################################
    ############ Properties ##################################################
    ##########################################################################

    ##########################################################################
    # Set the Control enabled or disabled

    @property
    def enabled(self):
        """
        Returns or set if the control is enable or disable.
        """
        return self.form.isEnabled()

    @enabled.setter
    def enabled(self, value):
        self.form.setEnabled(value)

    ##########################################################################
    # Return or update the value of the Control

    @property
    def value(self):
        """
        This property returns or set what the control should manage or store.
        """
        return self._value

    @value.setter
    def value(self, value):
        oldvalue = self._value
        self._value = value
        if oldvalue != value:
            self.changed_event()

    
    @property
    def name(self): 
        """
        This property returns or set the name of the control.
        """
        return self.form.objectName()

    @name.setter
    def name(self, value):
        self.form.setObjectName(value)

    ##########################################################################
    # Return or update the label of the Control

    @property
    def label(self):
        """
        Returns or sets the label of the control.
        """
        return self._label

    @label.setter
    def label(self, value):
        self._label = value

    ##########################################################################
    # Parent window

    @property
    def parent(self):
        """
        Returns or set the parent basewidget where the Control is.
        """
        return self._parent

    @parent.setter
    def parent(self, value):
        self._parent = value

    @property
    def visible(self):
        """
        Return the control visibility.
        """
        return self.form.isVisible()

    @property
    def help(self):
        """
        Returns or set the tip box of the control.
        """
        return self._help if self._help else ''

    @property
    def error(self): return None

    @error.setter
    def error(self, value):
        pass

    @property
    def label_visible(self): return None

    @label_visible.setter
    def label_visible(self, value):
        pass

    @property
    def readonly(self):
        """
        Set and return the control readonly state.
        """
        return None

    @readonly.setter
    def readonly(self, value):
        pass

    @property
    def css(self): return None

    @css.setter
    def css(self, value):
        pass


    ##########################################################################
    ############ Properties just for the GUI version #########################
    ##########################################################################

    ##########################################################################
    # Return the QT widget

    @property
    def form(self):
        """
        Returns the QWidget of the control.
        """
        return self._form
Esempio n. 28
0
 def __init__(self, parent, var, lc):
     QToolButton.__init__(self, parent)
     self.desc_text = ''
     self.popup = CheckBoxPopup(var, lc, parent, self)
     self.setMenu(QMenu())  # to show arrow
     self.clicked.connect(self.open_popup)
Esempio n. 29
0
    def _setup_gui(self):
        # control area
        library_box: QGroupBox = gui.vBox(self.controlArea, "Library")
        library_box.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Maximum)

        edit_triggers = QListView.DoubleClicked | QListView.EditKeyPressed
        self.__library_view = QListView(
            editTriggers=int(edit_triggers),
            minimumWidth=200,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Expanding),
        )
        self.__library_view.setFixedHeight(100)
        self.__library_view.setItemDelegate(LibraryItemDelegate(self))
        self.__library_view.setModel(self.__model)
        self.__library_view.selectionModel().selectionChanged.connect(
            self.__on_selection_changed
        )

        actions_widget = ModelActionsWidget()
        actions_widget.layout().setSpacing(1)

        tool_tip = "Add a new ontology to the library"
        action = QAction("+", self, toolTip=tool_tip)
        action.triggered.connect(self.__on_add)
        actions_widget.addAction(action)

        tool_tip = "Remove the ontology from the library"
        action = QAction("\N{MINUS SIGN}", self, toolTip=tool_tip)
        action.triggered.connect(self.__on_remove)
        actions_widget.addAction(action)

        tool_tip = "Save changes in the editor to the library"
        action = QAction("Update", self, toolTip=tool_tip)
        action.triggered.connect(self.__on_update)
        actions_widget.addAction(action)

        gui.rubber(actions_widget)

        action = QAction("More", self, toolTip="More actions")

        new_from_file = QAction("Import Ontology from File", self)
        new_from_file.triggered.connect(self.__on_import_file)

        new_from_url = QAction("Import Ontology from URL", self)
        new_from_url.triggered.connect(self.__on_import_url)

        save_to_file = QAction("Save Ontology to File", self)
        save_to_file.triggered.connect(self.__on_save)

        menu = QMenu(actions_widget)
        menu.addAction(new_from_file)
        menu.addAction(new_from_url)
        menu.addAction(save_to_file)
        action.setMenu(menu)
        button = actions_widget.addAction(action)
        button.setPopupMode(QToolButton.InstantPopup)

        vlayout = QVBoxLayout()
        vlayout.setSpacing(1)
        vlayout.setContentsMargins(0, 0, 0, 0)
        vlayout.addWidget(self.__library_view)
        vlayout.addWidget(actions_widget)

        library_box.layout().setSpacing(1)
        library_box.layout().addLayout(vlayout)

        input_box: QGroupBox = gui.vBox(self.controlArea, "Input")
        self.__input_view = ListViewSearch(
            sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Expanding),
            selectionMode=QListView.ExtendedSelection,
            dragEnabled=True,
        )
        self.__input_view.setModel(self.__input_model)
        self.__input_view.selectionModel().selectionChanged.connect(
            self._enable_include_button
        )

        self.__inc_button = gui.button(
            None, self, self.INC_BUTTON, enabled=False,
            toolTip="Include selected words into the ontology",
            autoDefault=False, callback=self.__on_toggle_include
        )

        input_box.layout().setSpacing(1)
        input_box.layout().addWidget(self.__input_view)
        input_box.layout().addWidget(self.__inc_button)

        self.__run_button = gui.button(
            self.controlArea, self, self.RUN_BUTTON,
            callback=self.__on_toggle_run
        )
        gui.checkBox(
            self.controlArea, self, "include_children", "Include subtree",
            box="Output", callback=self.commit.deferred
        )
        box = gui.vBox(self.controlArea, "Ontology info")
        gui.label(box, self, "%(ontology_info)s")

        gui.auto_send(self.buttonsArea, self, "auto_commit")

        # main area
        ontology_box: QGroupBox = gui.vBox(self.mainArea, box=True)

        self.__ontology_view = EditableTreeView(self)
        self.__ontology_view.dataChanged.connect(
            self.__on_ontology_data_changed
        )
        self.__ontology_view.selectionChanged.connect(self.commit.deferred)

        ontology_box.layout().setSpacing(1)
        ontology_box.layout().addWidget(self.__ontology_view)

        self._enable_include_button()
Esempio n. 30
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowIcon(QIcon(':/res/box.png'))

        self._tray = QSystemTrayIcon()
        self._tray.setIcon(QIcon(':/res/box.png'))
        self._tray.activated.connect(self.show_tray_menu)
        self._tray.show()
        self._menu = None
        self._action_screen = None
        self._action_clip = None
        self._screenshot_wnd = None
        self.rebuild_menu()

        self._hotkey = hotkeys.initialize()

        if not settings['initialized']:
            settings['initialized'] = True
            settings['hotkey/screenshot'] = 'Print'
            settings['hotkey/clipboard'] = 'Ctrl+Alt+P'
            settings.save()

        self.register_hotkeys()

    def rebuild_menu(self):
        # Terrible way to clear hotkey shortcuts set to actions because Qt can not do that.
        self._menu = QMenu()
        self._action_screen = self._menu.addAction(self.tr('Make Screenshot'))
        self._action_screen.triggered.connect(self.capture_screen)
        self._action_clip = self._menu.addAction(self.tr('Share Clipboard'))
        self._action_clip.triggered.connect(self.share_clipboard)
        self._menu.addSeparator()
        self._menu.addAction(self.tr('Settings')).triggered.connect(self.show_settings)
        self._menu.addSeparator()
        self._menu.addAction(self.tr('Exit')).triggered.connect(lambda: QApplication.exit(0))
        self._tray.setContextMenu(self._menu)

    def __del__(self):
        hotkey = getattr(self, '_hotkey', None)
        if hotkey:
            hotkey.destroy()

    def show_tray_menu(self):
        self._menu.popup(QCursor.pos())

    def capture_screen(self):
        if self._screenshot_wnd:
            return

        self._screenshot_wnd = wnd = Screenshot()
        result = wnd.exec_()
        self._screenshot_wnd = None
        if result == QDialog.Accepted:
            wnd = ShareDialog(self, image=wnd.selected_image)
            wnd.show()
            wnd.exec_()

    def share_clipboard(self):
        mime = QApplication.clipboard().mimeData()
        try:
            wnd = ShareDialog(self, mime=mime)
        except ValueError as e:
            QMessageBox.critical(self, self.tr('Error'), str(e))
            return
        else:
            wnd.show()
            wnd.exec_()

    def register_hotkeys(self):
        if self._hotkey is not None:
            self.rebuild_menu()
            self._hotkey.unregister(winid=self.winId())
            hotkey_bindings = {
                settings['hotkey/clipboard']: (self.share_clipboard, self._action_clip),
                settings['hotkey/screenshot']: (self.capture_screen, self._action_screen)
            }
            for hotkey, (callback, action) in hotkey_bindings.items():
                if hotkey:
                    if self._hotkey.register(hotkey, callback, self.winId()):
                        sequence = QKeySequence(hotkey) if hotkey else QKeySequence()
                        action.setShortcut(sequence)
                    else:
                        QMessageBox.critical(self, 'Error', 'Could not bind {} hotkey!\n'
                                                            'Key combination {} is probably already in use.'
                                             .format(const.APP_NAME, hotkey))
        else:
            qDebug('Hotkeys are not supported on this platform')

    def show_settings(self):
        self._hotkey.unregister(winid=self.winId())
        dlg = SettingsDialog(self)
        dlg.show()
        dlg.exec_()
        # WORKAROUND: On windows calling register_hotkeys() directly often results in a crash.
        QTimer.singleShot(10, self.register_hotkeys)
Esempio n. 31
0
    def __init__(self):
        super().__init__()

        self.in_data = None
        self.in_distance = None
        self.in_learner = None
        self.in_classifier = None
        self.in_object = None

        for s in self.libraryListSource:
            s.flags = 0

        self._cachedDocuments = {}

        self.infoBox = gui.vBox(self.controlArea, 'Info')
        gui.label(
            self.infoBox, self,
            "<p>Execute python script.</p><p>Input variables:<ul><li> " + \
            "<li>".join(t.name for t in self.inputs) + \
            "</ul></p><p>Output variables:<ul><li>" + \
            "<li>".join(t.name for t in self.outputs) + \
            "</ul></p>"
        )

        self.libraryList = itemmodels.PyListModel(
            [],
            self,
            flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)

        self.libraryList.wrap(self.libraryListSource)

        self.controlBox = gui.vBox(self.controlArea, 'Library')
        self.controlBox.layout().setSpacing(1)

        self.libraryView = QListView(
            editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred))
        self.libraryView.setItemDelegate(ScriptItemDelegate(self))
        self.libraryView.setModel(self.libraryList)

        self.libraryView.selectionModel().selectionChanged.connect(
            self.onSelectedScriptChanged)
        self.controlBox.layout().addWidget(self.libraryView)

        w = itemmodels.ModelActionsWidget()

        self.addNewScriptAction = action = QAction("+", self)
        action.setToolTip("Add a new script to the library")
        action.triggered.connect(self.onAddScript)
        w.addAction(action)

        action = QAction(unicodedata.lookup("MINUS SIGN"), self)
        action.setToolTip("Remove script from library")
        action.triggered.connect(self.onRemoveScript)
        w.addAction(action)

        action = QAction("Update", self)
        action.setToolTip("Save changes in the editor to library")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.triggered.connect(self.commitChangesToLibrary)
        w.addAction(action)

        action = QAction("More", self, toolTip="More actions")

        new_from_file = QAction("Import Script from File", self)
        save_to_file = QAction("Save Selected Script to File", self)
        save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs))

        new_from_file.triggered.connect(self.onAddScriptFromFile)
        save_to_file.triggered.connect(self.saveScript)

        menu = QMenu(w)
        menu.addAction(new_from_file)
        menu.addAction(save_to_file)
        action.setMenu(menu)
        button = w.addAction(action)
        button.setPopupMode(QToolButton.InstantPopup)

        w.layout().setSpacing(1)

        self.controlBox.layout().addWidget(w)

        self.execute_button = gui.auto_commit(self.controlArea,
                                              self,
                                              "auto_execute",
                                              "Execute",
                                              auto_label="Auto Execute")

        self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea)
        self.mainArea.layout().addWidget(self.splitCanvas)

        self.defaultFont = defaultFont = \
            "Monaco" if sys.platform == "darwin" else "Courier"

        self.textBox = gui.vBox(self, 'Python Script')
        self.splitCanvas.addWidget(self.textBox)
        self.text = PythonScriptEditor(self)
        self.textBox.layout().addWidget(self.text)

        self.textBox.setAlignment(Qt.AlignVCenter)
        self.text.setTabStopWidth(4)

        self.text.modificationChanged[bool].connect(self.onModificationChanged)

        self.saveAction = action = QAction("&Save", self.text)
        action.setToolTip("Save script to file")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.setShortcutContext(Qt.WidgetWithChildrenShortcut)
        action.triggered.connect(self.saveScript)

        self.consoleBox = gui.vBox(self, 'Console')
        self.splitCanvas.addWidget(self.consoleBox)
        self.console = PythonConsole({}, self)
        self.consoleBox.layout().addWidget(self.console)
        self.console.document().setDefaultFont(QFont(defaultFont))
        self.consoleBox.setAlignment(Qt.AlignBottom)
        self.console.setTabStopWidth(4)

        select_row(self.libraryView, self.currentScriptIndex)

        self.splitCanvas.setSizes([2, 1])
        if self.splitterState is not None:
            self.splitCanvas.restoreState(QByteArray(self.splitterState))

        self.splitCanvas.splitterMoved[int, int].connect(self.onSpliterMoved)
        self.controlArea.layout().addStretch(1)
        self.resize(800, 600)
Esempio n. 32
0
 def context(pos):
     menu = QMenu(view)
     menu.addActions(view.actions())
     a = menu.addAction("Aspect mode")
     am = QMenu(menu)
     am.addAction("Ignore",
                  lambda: view.setAspectMode(Qt.IgnoreAspectRatio))
     am.addAction("Keep", lambda: view.setAspectMode(Qt.KeepAspectRatio))
     am.addAction("Keep by expanding",
                  lambda: view.setAspectMode(Qt.KeepAspectRatioByExpanding))
     a.setMenu(am)
     menu.popup(view.viewport().mapToGlobal(pos))
Esempio n. 33
0
    def __init__(self):
        super().__init__()

        for name in self.signal_names:
            setattr(self, name, [])

        self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea)
        self.mainArea.layout().addWidget(self.splitCanvas)

        # Styling

        self.defaultFont = defaultFont = (
            'Menlo' if sys.platform == 'darwin' else 'Courier'
            if sys.platform in ['win32', 'cygwin'] else 'DejaVu Sans Mono')
        self.defaultFontSize = defaultFontSize = 13

        self.editorBox = gui.vBox(self, box="Editor", spacing=4)
        self.splitCanvas.addWidget(self.editorBox)

        darkMode = QApplication.instance().property('darkMode')
        scheme_name = 'Dark' if darkMode else 'Light'
        syntax_highlighting_scheme = SYNTAX_HIGHLIGHTING_STYLES[scheme_name]
        self.pygments_style_class = make_pygments_style(scheme_name)

        eFont = QFont(defaultFont)
        eFont.setPointSize(defaultFontSize)

        # Fake Signature

        self.func_sig = func_sig = FunctionSignature(
            self.editorBox, syntax_highlighting_scheme, eFont)

        # Editor

        editor = PythonEditor(self)
        editor.setFont(eFont)
        editor.setup_completer_appearance((300, 180), eFont)

        # Fake return

        return_stmt = ReturnStatement(self.editorBox,
                                      syntax_highlighting_scheme, eFont)
        self.return_stmt = return_stmt

        # Match indentation

        textEditBox = QWidget(self.editorBox)
        textEditBox.setLayout(QHBoxLayout())
        char_4_width = QFontMetrics(eFont).horizontalAdvance('0000')

        @editor.viewport_margins_updated.connect
        def _(width):
            func_sig.setIndent(width)
            textEditMargin = max(0, round(char_4_width - width))
            return_stmt.setIndent(textEditMargin + width)
            textEditBox.layout().setContentsMargins(textEditMargin, 0, 0, 0)

        self.text = editor
        textEditBox.layout().addWidget(editor)
        self.editorBox.layout().addWidget(func_sig)
        self.editorBox.layout().addWidget(textEditBox)
        self.editorBox.layout().addWidget(return_stmt)

        self.editorBox.setAlignment(Qt.AlignVCenter)
        self.text.setTabStopWidth(4)

        self.text.modificationChanged[bool].connect(self.onModificationChanged)

        # Controls

        self.editor_controls = gui.vBox(self.controlArea, box='Preferences')

        self.vim_box = gui.hBox(self.editor_controls, spacing=20)
        self.vim_indicator = VimIndicator(self.vim_box)

        vim_sp = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        vim_sp.setRetainSizeWhenHidden(True)
        self.vim_indicator.setSizePolicy(vim_sp)

        def enable_vim_mode():
            editor.vimModeEnabled = self.vimModeEnabled
            self.vim_indicator.setVisible(self.vimModeEnabled)

        enable_vim_mode()

        gui.checkBox(self.vim_box,
                     self,
                     'vimModeEnabled',
                     'Vim mode',
                     tooltip="Only for the coolest.",
                     callback=enable_vim_mode)
        self.vim_box.layout().addWidget(self.vim_indicator)

        @editor.vimModeIndicationChanged.connect
        def _(color, text):
            self.vim_indicator.indicator_color = color
            self.vim_indicator.indicator_text = text
            self.vim_indicator.update()

        # Library

        self.libraryListSource = []
        self._cachedDocuments = {}

        self.libraryList = itemmodels.PyListModel(
            [],
            self,
            flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)

        self.libraryList.wrap(self.libraryListSource)

        self.controlBox = gui.vBox(self.controlArea, 'Library')
        self.controlBox.layout().setSpacing(1)

        self.libraryView = QListView(
            editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred))
        self.libraryView.setItemDelegate(ScriptItemDelegate(self))
        self.libraryView.setModel(self.libraryList)

        self.libraryView.selectionModel().selectionChanged.connect(
            self.onSelectedScriptChanged)
        self.controlBox.layout().addWidget(self.libraryView)

        w = itemmodels.ModelActionsWidget()

        self.addNewScriptAction = action = QAction("+", self)
        action.setToolTip("Add a new script to the library")
        action.triggered.connect(self.onAddScript)
        w.addAction(action)

        action = QAction(unicodedata.lookup("MINUS SIGN"), self)
        action.setToolTip("Remove script from library")
        action.triggered.connect(self.onRemoveScript)
        w.addAction(action)

        action = QAction("Update", self)
        action.setToolTip("Save changes in the editor to library")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.triggered.connect(self.commitChangesToLibrary)
        w.addAction(action)

        action = QAction("More", self, toolTip="More actions")

        new_from_file = QAction("Import Script from File", self)
        save_to_file = QAction("Save Selected Script to File", self)
        restore_saved = QAction("Undo Changes to Selected Script", self)
        save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs))

        new_from_file.triggered.connect(self.onAddScriptFromFile)
        save_to_file.triggered.connect(self.saveScript)
        restore_saved.triggered.connect(self.restoreSaved)

        menu = QMenu(w)
        menu.addAction(new_from_file)
        menu.addAction(save_to_file)
        menu.addAction(restore_saved)
        action.setMenu(menu)
        button = w.addAction(action)
        button.setPopupMode(QToolButton.InstantPopup)

        w.layout().setSpacing(1)

        self.controlBox.layout().addWidget(w)

        self.execute_button = gui.button(self.buttonsArea,
                                         self,
                                         'Run',
                                         callback=self.commit)

        self.run_action = QAction("Run script",
                                  self,
                                  triggered=self.commit,
                                  shortcut=QKeySequence(Qt.ControlModifier
                                                        | Qt.Key_R))
        self.addAction(self.run_action)

        self.saveAction = action = QAction("&Save", self.text)
        action.setToolTip("Save script to file")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.setShortcutContext(Qt.WidgetWithChildrenShortcut)
        action.triggered.connect(self.saveScript)

        self.consoleBox = gui.vBox(self.splitCanvas, 'Console')
        self.console = PythonConsole({}, self)
        self.consoleBox.layout().addWidget(self.console)
        self.console.document().setDefaultFont(QFont(defaultFont))
        self.consoleBox.setAlignment(Qt.AlignBottom)
        self.splitCanvas.setSizes([2, 1])
        self.controlArea.layout().addStretch(10)

        self._restoreState()
        self.settingsAboutToBePacked.connect(self._saveState)
 def contextMenuEvent(self, event):
     if self._actions:
         self._menu = menu = QMenu()
         for action in self._actions:
             menu.addAction(action)
         menu.popup(event.screenPos())
Esempio n. 35
0
    def __init__(self):
        super().__init__()
        self.data = None
        self.editors = {}

        box = gui.vBox(self.controlArea, "Variable Definitions")

        toplayout = QHBoxLayout()
        toplayout.setContentsMargins(0, 0, 0, 0)
        box.layout().addLayout(toplayout)

        self.editorstack = QStackedWidget(
            sizePolicy=QSizePolicy(QSizePolicy.MinimumExpanding,
                                   QSizePolicy.MinimumExpanding)
        )

        for descclass, editorclass in self.EDITORS:
            editor = editorclass()
            editor.featureChanged.connect(self._on_modified)
            self.editors[descclass] = editor
            self.editorstack.addWidget(editor)

        self.editorstack.setEnabled(False)

        buttonlayout = QVBoxLayout(spacing=10)
        buttonlayout.setContentsMargins(0, 0, 0, 0)

        self.addbutton = QPushButton(
            "New", toolTip="Create a new variable",
            minimumWidth=120,
            shortcut=QKeySequence.New
        )

        def unique_name(fmt, reserved):
            candidates = (fmt.format(i) for i in count(1))
            return next(c for c in candidates if c not in reserved)

        def reserved_names():
            varnames = []
            if self.data is not None:
                varnames = [var.name for var in
                            self.data.domain.variables + self.data.domain.metas]
            varnames += [desc.name for desc in self.featuremodel]
            return set(varnames)

        def generate_newname(fmt):
            return unique_name(fmt, reserved_names())

        menu = QMenu(self.addbutton)
        cont = menu.addAction("Numeric")
        cont.triggered.connect(
            lambda: self.addFeature(
                ContinuousDescriptor(generate_newname("X{}"), "", 3))
        )
        disc = menu.addAction("Categorical")
        disc.triggered.connect(
            lambda: self.addFeature(
                DiscreteDescriptor(generate_newname("D{}"), "",
                                   ("A", "B"), -1, False))
        )
        string = menu.addAction("Text")
        string.triggered.connect(
            lambda: self.addFeature(
                StringDescriptor(generate_newname("S{}"), ""))
        )
        menu.addSeparator()
        self.duplicateaction = menu.addAction("Duplicate Selected Variable")
        self.duplicateaction.triggered.connect(self.duplicateFeature)
        self.duplicateaction.setEnabled(False)
        self.addbutton.setMenu(menu)

        self.removebutton = QPushButton(
            "Remove", toolTip="Remove selected variable",
            minimumWidth=120,
            shortcut=QKeySequence.Delete
        )
        self.removebutton.clicked.connect(self.removeSelectedFeature)

        buttonlayout.addWidget(self.addbutton)
        buttonlayout.addWidget(self.removebutton)
        buttonlayout.addStretch(10)

        toplayout.addLayout(buttonlayout, 0)
        toplayout.addWidget(self.editorstack, 10)

        # Layout for the list view
        layout = QVBoxLayout(spacing=1, margin=0)
        self.featuremodel = DescriptorModel(parent=self)

        self.featureview = QListView(
            minimumWidth=200,
            sizePolicy=QSizePolicy(QSizePolicy.Minimum,
                                   QSizePolicy.MinimumExpanding)
        )

        self.featureview.setItemDelegate(FeatureItemDelegate(self))
        self.featureview.setModel(self.featuremodel)
        self.featureview.selectionModel().selectionChanged.connect(
            self._on_selectedVariableChanged
        )

        layout.addWidget(self.featureview)

        box.layout().addLayout(layout, 1)

        box = gui.hBox(self.controlArea)
        gui.rubber(box)
        commit = gui.button(box, self, "Send", callback=self.apply,
                            default=True)
        commit.setMinimumWidth(180)
Esempio n. 36
0
    def __init__(self):
        super().__init__()
        self.data = None
        self.editors = {}

        box = gui.vBox(self.controlArea, "Variable Definitions")

        toplayout = QHBoxLayout()
        toplayout.setContentsMargins(0, 0, 0, 0)
        box.layout().addLayout(toplayout)

        self.editorstack = QStackedWidget(
            sizePolicy=QSizePolicy(QSizePolicy.MinimumExpanding,
                                   QSizePolicy.MinimumExpanding)
        )

        for descclass, editorclass in self.EDITORS:
            editor = editorclass()
            editor.featureChanged.connect(self._on_modified)
            self.editors[descclass] = editor
            self.editorstack.addWidget(editor)

        self.editorstack.setEnabled(False)

        buttonlayout = QVBoxLayout(spacing=10)
        buttonlayout.setContentsMargins(0, 0, 0, 0)

        self.addbutton = QPushButton(
            "New", toolTip="Create a new variable",
            minimumWidth=120,
            shortcut=QKeySequence.New
        )

        def unique_name(fmt, reserved):
            candidates = (fmt.format(i) for i in count(1))
            return next(c for c in candidates if c not in reserved)

        def reserved_names():
            varnames = []
            if self.data is not None:
                varnames = [var.name for var in
                            self.data.domain.variables + self.data.domain.metas]
            varnames += [desc.name for desc in self.featuremodel]
            return set(varnames)

        def generate_newname(fmt):
            return unique_name(fmt, reserved_names())

        menu = QMenu(self.addbutton)
        cont = menu.addAction("Continuous")
        cont.triggered.connect(
            lambda: self.addFeature(
                ContinuousDescriptor(generate_newname("X{}"), "", 3))
        )
        disc = menu.addAction("Discrete")
        disc.triggered.connect(
            lambda: self.addFeature(
                DiscreteDescriptor(generate_newname("D{}"), "",
                                   ("A", "B"), -1, False))
        )
        string = menu.addAction("String")
        string.triggered.connect(
            lambda: self.addFeature(
                StringDescriptor(generate_newname("S{}"), ""))
        )
        menu.addSeparator()
        self.duplicateaction = menu.addAction("Duplicate Selected Variable")
        self.duplicateaction.triggered.connect(self.duplicateFeature)
        self.duplicateaction.setEnabled(False)
        self.addbutton.setMenu(menu)

        self.removebutton = QPushButton(
            "Remove", toolTip="Remove selected variable",
            minimumWidth=120,
            shortcut=QKeySequence.Delete
        )
        self.removebutton.clicked.connect(self.removeSelectedFeature)

        buttonlayout.addWidget(self.addbutton)
        buttonlayout.addWidget(self.removebutton)
        buttonlayout.addStretch(10)

        toplayout.addLayout(buttonlayout, 0)
        toplayout.addWidget(self.editorstack, 10)

        # Layout for the list view
        layout = QVBoxLayout(spacing=1, margin=0)
        self.featuremodel = DescriptorModel(parent=self)

        self.featureview = QListView(
            minimumWidth=200,
            sizePolicy=QSizePolicy(QSizePolicy.Minimum,
                                   QSizePolicy.MinimumExpanding)
        )

        self.featureview.setItemDelegate(FeatureItemDelegate(self))
        self.featureview.setModel(self.featuremodel)
        self.featureview.selectionModel().selectionChanged.connect(
            self._on_selectedVariableChanged
        )

        layout.addWidget(self.featureview)

        box.layout().addLayout(layout, 1)

        box = gui.hBox(self.controlArea)
        box.layout().addWidget(self.report_button)
        self.report_button.setMinimumWidth(180)
        gui.rubber(box)
        commit = gui.button(box, self, "Send", callback=self.apply,
                            default=True)
        commit.setMinimumWidth(180)
Esempio n. 37
0
    def _on_view_context_menu(self, pos):
        widget = self.scene.widget
        if widget is None:
            return
        assert isinstance(widget, HeatmapGridWidget)
        menu = QMenu(self.view.viewport())
        menu.setAttribute(Qt.WA_DeleteOnClose)
        menu.addActions(self.view.actions())
        menu.addSeparator()
        menu.addActions([self.__font_inc, self.__font_dec])
        menu.addSeparator()
        a = QAction("Keep aspect ratio", menu, checkable=True)
        a.setChecked(self.keep_aspect)

        def ontoggled(state):
            self.keep_aspect = state
            self.__aspect_mode_changed()

        a.toggled.connect(ontoggled)
        menu.addAction(a)
        menu.popup(self.view.viewport().mapToGlobal(pos))
Esempio n. 38
0
	def add_popup_submenu(self, label, submenu=None):
		self.__create_popup_menu()
		menu = submenu if submenu else self._popup_menu
		submenu = QMenu(label, menu)
		menu.addMenu(submenu)
		return submenu
Esempio n. 39
0
class ControlBase(object):
	"""
	This class represents the most basic control that can exist
	A Control is a Widget or a group of widgets that can be reused from application to application

	@undocumented: __repr__
	"""

	def __init__(self, label='', default=None, helptext=None):
		self._help      = helptext
		self._value     = default
		self._form      = None  # Qt widget
		self._parent    = None  # Parent window
		self._label     = label # Label
		self._popup_menu = None
		
		self.init_form()


	def init_form(self):
		"""
		Load Control and initiate the events
		"""		
		if self.help: self.form.setToolTip(self.help)


	def __repr__(self): return str(self._value)

	##########################################################################
	############ Funcions ####################################################
	##########################################################################

	def load_form(self, data, path=None):
		"""
		Load a value from the dict variable
		@param data: dictionary with the value of the Control
		"""
		if 'value' in data:
			self.value = data['value']

	def save_form(self, data, path=None):
		"""
		Save a value to dict variable
		@param data: dictionary with to where the value of the Control will be added
		"""
		if self.value:
			data['value'] = self.value
		return data

	def show(self):
		"""
		Show the control
		"""
		if self.form is None:
			return
		self.form.show()

	def hide(self):
		"""
		Hide the control
		"""
		if self.form is None:
			return
		self.form.hide()


	def __create_popup_menu(self):
		if not self._popup_menu:
			self.form.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
			self.form.customContextMenuRequested.connect(self._open_popup_menu)
			self._popup_menu = QMenu(self.parent)
			self._popup_menu.aboutToShow.connect( self.about_to_show_contextmenu_event)

	def add_popup_submenu(self, label, submenu=None):
		self.__create_popup_menu()
		menu = submenu if submenu else self._popup_menu
		submenu = QMenu(label, menu)
		menu.addMenu(submenu)
		return submenu

	def add_popup_menu_option(self, label, function_action=None, key=None, icon=None, submenu=None):
		"""
		Add an option to the Control popup menu
		@param label:           label of the option.
		@param function_action:  function called when the option is selected.
		@param key:             shortcut key
		@param icon:            icon
		"""
		self.__create_popup_menu()

		menu = submenu if submenu else self._popup_menu

		if label == "-":
			return menu.addSeparator()
		else:
			action = QAction(label, self.form)
			if icon is not None:
				action.setIconVisibleInMenu(True)
				action.setIcon(icon if isinstance(icon, QIcon) else QIcon(icon) )
			if key != None:
				action.setShortcut(QKeySequence(key))
			if function_action:
				action.triggered.connect(function_action)
				menu.addAction(action)
			return action


	##########################################################################
	############ Events ######################################################
	##########################################################################

	def changed_event(self):
		"""
		Function called when ever the Control value is changed
		"""
		return True

	def about_to_show_contextmenu_event(self):
		"""
		Function called before open the Control popup menu
		"""
		pass

	def _open_popup_menu(self, position):
		if self._popup_menu:
			self._popup_menu.exec_(self.form.mapToGlobal(position))

	##########################################################################
	############ Properties ##################################################
	##########################################################################

	##########################################################################
	# Set the Control enabled or disabled

	@property
	def enabled(self):
		return self.form.isEnabled()

	@enabled.setter
	def enabled(self, value):
		"""@type  value: boolean"""
		self.form.setEnabled(value)

	##########################################################################
	# Return or update the value of the Control

	@property
	def value(self):
		return self._value

	@value.setter
	def value(self, value):
		"""
		This property return and set what the control should manage or store.
		@type  value: string
		"""
		oldvalue = self._value
		self._value = value
		if oldvalue != value:
			self.changed_event()

	@property
	def visible(self): return self.form.isVisible()

	@visible.setter
	def visible(self, value):
		self.show() if value else self.hide()

	@property
	def name(self): return self.form.objectName()

	@name.setter
	def name(self, value):
		"""
		This property return and set the name of the control
		@type  value: string
		"""
		self.form.setObjectName(value)

	##########################################################################
	# Return or update the label of the Control

	@property
	def label(self):
		return self._label

	@label.setter
	def label(self, value):
		"""
		Label of the control, if applies
		@type  value: string
		"""
		self._label = value

	##########################################################################
	# Return the QT widget

	@property
	def form(self):
		"""
		Returns the Widget of the control. 
		This property will be deprecated in a future version.
		"""
		return self._form

	##########################################################################
	# Parent window

	@property
	def parent(self): return self._parent

	@parent.setter
	def parent(self, value):
		"""
		Returns or set the parent basewidget where the Control is
		@type  value: BaseWidget
		"""
		self._parent = value

	@property
	def help(self): return self._help if self._help else ''
Esempio n. 40
0
    def __init__(self):
        super().__init__()
        self.libraryListSource = []

        for name in self.signal_names:
            setattr(self, name, {})

        self._cachedDocuments = {}

        self.infoBox = gui.vBox(self.controlArea, 'Info')
        gui.label(
            self.infoBox, self,
            "<p>Execute python script.</p><p>Input variables:<ul><li> " +
            "<li>".join(map("in_{0}, in_{0}s".format, self.signal_names)) +
            "</ul></p><p>Output variables:<ul><li>" +
            "<li>".join(map("out_{0}".format, self.signal_names)) +
            "</ul></p>")

        self.libraryList = itemmodels.PyListModel(
            [],
            self,
            flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)

        self.libraryList.wrap(self.libraryListSource)

        self.controlBox = gui.vBox(self.controlArea, 'Library')
        self.controlBox.layout().setSpacing(1)

        self.libraryView = QListView(
            editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred))
        self.libraryView.setItemDelegate(ScriptItemDelegate(self))
        self.libraryView.setModel(self.libraryList)

        self.libraryView.selectionModel().selectionChanged.connect(
            self.onSelectedScriptChanged)
        self.controlBox.layout().addWidget(self.libraryView)

        w = itemmodels.ModelActionsWidget()

        self.addNewScriptAction = action = QAction("+", self)
        action.setToolTip("Add a new script to the library")
        action.triggered.connect(self.onAddScript)
        w.addAction(action)

        action = QAction(unicodedata.lookup("MINUS SIGN"), self)
        action.setToolTip("Remove script from library")
        action.triggered.connect(self.onRemoveScript)
        w.addAction(action)

        action = QAction("Update", self)
        action.setToolTip("Save changes in the editor to library")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.triggered.connect(self.commitChangesToLibrary)
        w.addAction(action)

        action = QAction("More", self, toolTip="More actions")

        new_from_file = QAction("Import Script from File", self)
        save_to_file = QAction("Save Selected Script to File", self)
        restore_saved = QAction("Undo Changes to Selected Script", self)
        save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs))

        new_from_file.triggered.connect(self.onAddScriptFromFile)
        save_to_file.triggered.connect(self.saveScript)
        restore_saved.triggered.connect(self.restoreSaved)

        menu = QMenu(w)
        menu.addAction(new_from_file)
        menu.addAction(save_to_file)
        menu.addAction(restore_saved)
        action.setMenu(menu)
        button = w.addAction(action)
        button.setPopupMode(QToolButton.InstantPopup)

        w.layout().setSpacing(1)

        self.controlBox.layout().addWidget(w)

        self.execute_button = gui.button(self.controlArea,
                                         self,
                                         'Run',
                                         callback=self.commit)

        run = QAction("Run script",
                      self,
                      triggered=self.commit,
                      shortcut=QKeySequence(Qt.ControlModifier | Qt.Key_R))
        self.addAction(run)

        self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea)
        self.mainArea.layout().addWidget(self.splitCanvas)

        self.defaultFont = defaultFont = \
            "Monaco" if sys.platform == "darwin" else "Courier"

        self.textBox = gui.vBox(self, 'Python Script')
        self.splitCanvas.addWidget(self.textBox)
        self.text = PythonScriptEditor(self)
        self.textBox.layout().addWidget(self.text)

        self.textBox.setAlignment(Qt.AlignVCenter)
        self.text.setTabStopWidth(4)

        self.text.modificationChanged[bool].connect(self.onModificationChanged)

        self.saveAction = action = QAction("&Save", self.text)
        action.setToolTip("Save script to file")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.setShortcutContext(Qt.WidgetWithChildrenShortcut)
        action.triggered.connect(self.saveScript)

        self.consoleBox = gui.vBox(self, 'Console')
        self.splitCanvas.addWidget(self.consoleBox)
        self.console = PythonConsole({}, self)
        self.consoleBox.layout().addWidget(self.console)
        self.console.document().setDefaultFont(QFont(defaultFont))
        self.consoleBox.setAlignment(Qt.AlignBottom)
        self.console.setTabStopWidth(4)
        self.splitCanvas.setSizes([2, 1])
        self.setAcceptDrops(True)
        self.controlArea.layout().addStretch(10)

        self._restoreState()
        self.settingsAboutToBePacked.connect(self._saveState)
Esempio n. 41
0
    def __init__(self):
        super().__init__()

        for name in self.signal_names:
            setattr(self, name, {})

        for s in self.libraryListSource:
            s.flags = 0

        self._cachedDocuments = {}

        self.infoBox = gui.vBox(self.controlArea, '信息')
        gui.label(
            self.infoBox, self, "<p>执行Python脚本。</p><p>输入变量:<ul><li> " +
            "<li>".join(map("in_{0}, in_{0}s".format, self.signal_names)) +
            "</ul></p><p>输出变量:<ul><li>" +
            "<li>".join(map("out_{0}".format, self.signal_names)) +
            "</ul></p>")

        self.libraryList = itemmodels.PyListModel(
            [],
            self,
            flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)

        self.libraryList.wrap(self.libraryListSource)

        self.controlBox = gui.vBox(self.controlArea, '脚本库')
        self.controlBox.layout().setSpacing(1)

        self.libraryView = QListView(
            editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred))
        self.libraryView.setItemDelegate(ScriptItemDelegate(self))
        self.libraryView.setModel(self.libraryList)

        self.libraryView.selectionModel().selectionChanged.connect(
            self.onSelectedScriptChanged)
        self.controlBox.layout().addWidget(self.libraryView)

        w = itemmodels.ModelActionsWidget()

        self.addNewScriptAction = action = QAction("+", self)
        action.setToolTip("向库中添加新脚本")
        action.triggered.connect(self.onAddScript)
        w.addAction(action)

        action = QAction(unicodedata.lookup("MINUS SIGN"), self)
        action.setToolTip("从库中删除脚本")
        action.triggered.connect(self.onRemoveScript)
        w.addAction(action)

        action = QAction("保存", self)
        action.setToolTip("将编辑器中的更改的脚本保存到库中")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.triggered.connect(self.commitChangesToLibrary)
        w.addAction(action)

        action = QAction("更多", self, toolTip="更多操作")

        new_from_file = QAction("从文件导入脚本", self)
        save_to_file = QAction("将所选脚本保存到文件", self)
        save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs))

        new_from_file.triggered.connect(self.onAddScriptFromFile)
        save_to_file.triggered.connect(self.saveScript)

        menu = QMenu(w)
        menu.addAction(new_from_file)
        menu.addAction(save_to_file)
        action.setMenu(menu)
        button = w.addAction(action)
        button.setPopupMode(QToolButton.InstantPopup)

        w.layout().setSpacing(1)

        self.controlBox.layout().addWidget(w)

        auto = gui.auto_commit(self.controlArea,
                               self,
                               "auto_execute",
                               "运行",
                               checkbox_label="对新数据自动运行")
        self.execute_button, self.autobox = auto.button, auto.checkbox

        self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea)
        self.mainArea.layout().addWidget(self.splitCanvas)

        self.defaultFont = defaultFont = \
            "Monaco" if sys.platform == "darwin" else "Courier"

        self.textBox = gui.vBox(self, 'Python脚本')
        self.splitCanvas.addWidget(self.textBox)
        self.text = PythonScriptEditor(self)
        self.textBox.layout().addWidget(self.text)

        self.textBox.setAlignment(Qt.AlignVCenter)
        self.text.setTabStopWidth(4)

        self.text.modificationChanged[bool].connect(self.onModificationChanged)

        self.saveAction = action = QAction("&Save", self.text)
        action.setToolTip("Save script to file")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.setShortcutContext(Qt.WidgetWithChildrenShortcut)
        action.triggered.connect(self.saveScript)

        self.consoleBox = gui.vBox(self, '控制台')
        self.splitCanvas.addWidget(self.consoleBox)
        self.console = PythonConsole({}, self)
        self.consoleBox.layout().addWidget(self.console)
        self.console.document().setDefaultFont(QFont(defaultFont))
        self.consoleBox.setAlignment(Qt.AlignBottom)
        self.console.setTabStopWidth(4)

        select_row(self.libraryView, self.currentScriptIndex)

        self.splitCanvas.setSizes([2, 1])
        if self.splitterState is not None:
            self.splitCanvas.restoreState(QByteArray(self.splitterState))

        self.splitCanvas.splitterMoved[int, int].connect(self.onSpliterMoved)
        self.controlArea.layout().addStretch(1)
        self.resize(800, 600)