Пример #1
0
def get_icon_html(icon: QIcon, size: QSize) -> str:
    """
    Transform an icon to html <img> tag.
    """
    if not size.isValid():
        return ""
    if size.width() < 0 or size.height() < 0:
        size = QSize(16, 16)  # just in case
    byte_array = QByteArray()
    buffer = QBuffer(byte_array)
    buffer.open(QIODevice.WriteOnly)
    pixmap = icon.pixmap(size)
    if pixmap.isNull():
        return ""
    pixmap.save(buffer, "PNG")
    buffer.close()

    dpr = pixmap.devicePixelRatioF()
    if dpr != 1.0:
        size_ = pixmap.size() / dpr
        size_part = ' width="{}" height="{}"'.format(
            int(math.floor(size_.width())), int(math.floor(size_.height()))
        )
    else:
        size_part = ''
    img_encoded = byte_array.toBase64().data().decode("utf-8")
    return '<img src="data:image/png;base64,{}"{}/>'.format(img_encoded, size_part)
Пример #2
0
def get_html_img(scene):
    """
    Create HTML img element with base64-encoded image from the scene
    """
    byte_array = QByteArray()
    filename = QBuffer(byte_array)
    filename.open(QIODevice.WriteOnly)
    PngFormat.write(filename, scene)
    img_encoded = byte_array.toBase64().data().decode("utf-8")
    return "<img src='data:image/png;base64,%s'/>" % img_encoded
Пример #3
0
def get_html_img(scene):
    """
    Create HTML img element with base64-encoded image from the scene
    """
    byte_array = QByteArray()
    filename = QBuffer(byte_array)
    filename.open(QIODevice.WriteOnly)
    PngFormat.write(filename, scene)
    img_encoded = byte_array.toBase64().data().decode("utf-8")
    return "<img src='data:image/png;base64,%s'/>" % img_encoded
Пример #4
0
def table_selection_to_mime_data(table):
    """Copy the current selection in a QTableView to the clipboard.
    """
    lines = table_selection_to_list(table)

    as_csv = lines_to_csv_string(lines, dialect="excel").encode("utf-8")
    as_tsv = lines_to_csv_string(lines, dialect="excel-tab").encode("utf-8")

    mime = QMimeData()
    mime.setData("text/csv", QByteArray(as_csv))
    mime.setData("text/tab-separated-values", QByteArray(as_tsv))
    mime.setData("text/plain", QByteArray(as_tsv))
    return mime
Пример #5
0
def get_html_img(scene: QGraphicsScene,
                 max_height: Optional[int] = None) -> str:
    """
    Create HTML img element with base64-encoded image from the scene.
    If max_height is not none set the max height of the image in html.
    """
    byte_array = QByteArray()
    filename = QBuffer(byte_array)
    filename.open(QIODevice.WriteOnly)
    PngFormat.write(filename, scene)
    img_encoded = byte_array.toBase64().data().decode("utf-8")
    return '<img {} src="data:image/png;base64,{}"/>'.format(
        ("" if max_height is None else
         'style="max-height: {}px"'.format(max_height)), img_encoded)
Пример #6
0
    def restore_window_state(self, state):
        # type: (List[Tuple[SchemeNode, bytes]]) -> None
        """
        Restore the window state.
        """
        workflow = self.__scheme  # type: WidgetsScheme
        visible = {node for node, _ in state}
        # first hide all other widgets
        for node in workflow.nodes:
            if node not in visible:
                # avoid creating widgets if not needed
                w = self.__widget_for_node.get(node, None)
                if w is not None:
                    w.hide()
        allnodes = set(workflow.nodes)
        # restore state for visible group; windows are stacked as they appear
        # in the state list.
        w = None
        for node, state in filter(lambda t: t[0] in allnodes, state):
            w = self.widget_for_node(node)  # also create it if needed
            w.show()
            w.restoreGeometryAndLayoutState(QByteArray(state))
            w.raise_()
            self.__mark_activated(w)

        # activate (give focus to) the last window
        if w is not None:
            w.activateWindow()
Пример #7
0
    def restoreGeometryAndLayoutState(self, state):
        # type: (QByteArray) -> bool
        """
        Restore the geometry and layout of this widget to a state previously
        saved with :func:`saveGeometryAndLayoutState`.

        Parameters
        ----------
        state : QByteArray
            Saved state.

        Returns
        -------
        success : bool
            `True` if the state was successfully restored, `False` otherwise.
        """
        version = 0x1
        stream = QDataStream(state, QBuffer.ReadOnly)
        version_ = stream.readUInt32()
        if stream.status() != QDataStream.Ok or version_ != version:
            return False
        splitter_state = stream.readUInt16()
        has_spliter = splitter_state & 0x2
        splitter_state = splitter_state & 0x1
        if has_spliter and self.__splitter is not None:
            self.__splitter.setControlAreaVisible(bool(splitter_state))
        geometry = QByteArray()
        stream >> geometry
        if stream.status() == QDataStream.Ok:
            return self.__restoreWidgetGeometry(bytes(geometry))
        else:
            return False  # pragma: no cover
Пример #8
0
 def restore_widget_geometry_for_node(self, node, state):
     # type: (SchemeNode, bytes) -> bool
     w = self.widget_for_node(node)
     if w is not None:
         return w.restoreGeometryAndLayoutState(QByteArray(state))
     else:
         return False
Пример #9
0
 def _fullscreen_to_maximized(geometry):
     """Don't restore windows into full screen mode because it loses
     decorations and can't be de-fullscreened at least on some platforms.
     Use Maximized state insted."""
     w = QWidget(visible=False)
     w.restoreGeometry(QByteArray(geometry))
     if w.isFullScreen():
         w.setWindowState(w.windowState() & ~Qt.WindowFullScreen
                          | Qt.WindowMaximized)
     return w.saveGeometry()
Пример #10
0
    def mimeData(self, indexlist):
        if len(indexlist) <= 0:
            return None

        items = [self[i.row()] for i in indexlist]
        mime = QAbstractListModel.mimeData(self, indexlist)
        data = pickle.dumps(vars)
        mime.set_data(self.MIME_TYPE, QByteArray(data))
        mime._items = items
        return mime
    def restore_widget_geometry(self, node, widget, state):
        # type: (SchemeNode, QWidget, bytes) -> bool
        """
        Restore the widget geometry state.

        Reimplemented.
        """
        if isinstance(widget, OWBaseWidget):
            return widget.restoreGeometryAndLayoutState(QByteArray(state))
        else:
            return super().restore_widget_geometry(node, widget)
Пример #12
0
    def test_store_restore_layout_geom(self):
        class Widget(OWBaseWidget):
            name = "Who"
            want_control_area = True

        w = Widget()
        w._OWBaseWidget__setControlAreaVisible(False)
        w.setGeometry(QRect(51, 52, 53, 54))
        state = w.saveGeometryAndLayoutState()
        w1 = Widget()
        self.assertTrue(w1.restoreGeometryAndLayoutState(state))
        self.assertEqual(w1.geometry(), QRect(51, 52, 53, 54))
        self.assertFalse(w1.controlAreaVisible)

        Widget.want_control_area = False
        w2 = Widget()
        self.assertTrue(w2.restoreGeometryAndLayoutState(state))
        self.assertEqual(w1.geometry(), QRect(51, 52, 53, 54))

        self.assertFalse((w2.restoreGeometryAndLayoutState(QByteArray())))
        self.assertFalse(w2.restoreGeometryAndLayoutState(QByteArray(b'ab')))
Пример #13
0
 def mimeData(self, indexlist):
     descriptors = []
     vars = []
     for index in indexlist:
         var = self[index.row()]
         descriptors.append((var.name, vartype(var)))
         vars.append(var)
     mime = QMimeData()
     mime.setData(self.MIME_TYPE,
                  QByteArray(str(descriptors).encode("utf-8")))
     mime._vars = vars
     return mime
Пример #14
0
    def _restoreState(self):
        self.libraryListSource = [Script.fromdict(s) for s in self.scriptLibrary]
        self.libraryList.wrap(self.libraryListSource)
        select_row(self.libraryView, self.currentScriptIndex)

        if self.scriptText is not None:
            current = self.text.toPlainText()
            # do not mark scripts as modified
            if self.scriptText != current:
                self.text.document().setPlainText(self.scriptText)

        if self.splitterState is not None:
            self.splitCanvas.restoreState(QByteArray(self.splitterState))
Пример #15
0
    def __update(self):
        """Update the current description.
        """
        if self.__currentIndex != -1:
            index = self.model().index(self.__currentIndex, 0)
        else:
            index = QModelIndex()

        if not index.isValid():
            description = ""
            name = ""
            path = ""
            svg = NO_PREVIEW_SVG
        else:
            description = qtcompat.qunwrap(index.data(Qt.WhatsThisRole))
            if description:
                description = six.text_type(description)
            else:
                description = u"No description."

            description = escape(description)
            description = description.replace("\n", "<br/>")

            name = qtcompat.qunwrap(index.data(Qt.DisplayRole))
            if name:
                name = six.text_type(name)
            else:
                name = "Untitled"

            name = escape(name)
            path = qtcompat.qunwrap(index.data(Qt.StatusTipRole))
            path = six.text_type(path)

            svg = qtcompat.qunwrap(index.data(previewmodel.ThumbnailSVGRole))
            svg = six.text_type(svg)

        desc_text = self.__template.format(description=description, name=name)

        self.__label.setText(desc_text)

        self.__path.setText(path)

        if not svg:
            svg = NO_PREVIEW_SVG

        if svg:
            self.__image.load(QByteArray(svg.encode("utf-8")))
Пример #16
0
    def __update(self):
        # type: () -> None
        """Update the current description.
        """
        if self.__currentIndex != -1 and self.__model is not None:
            index = self.__model.index(self.__currentIndex, 0)
        else:
            index = QModelIndex()

        if not index.isValid():
            description = ""
            name = ""
            path = ""
            svg = NO_PREVIEW_SVG
        else:
            description = index.data(Qt.WhatsThisRole)
            if description:
                description = description
            else:
                description = "没有说明。"

            description = escape(description)
            description = description.replace("\n", "<br/>")

            name = index.data(Qt.DisplayRole)
            if name:
                name = name
            else:
                name = "Untitled"

            name = escape(name)
            path = str(index.data(Qt.StatusTipRole))
            svg = str(index.data(previewmodel.ThumbnailSVGRole))

        desc_text = self.__template.format(description=description, name=name)

        self.__label.setText(desc_text)

        self.__path.setText(contractuser(path))

        if not svg:
            svg = NO_PREVIEW_SVG

        if svg:
            self.__image.load(QByteArray(svg.encode("utf-8")))
Пример #17
0
    def saveState(self):  # type: () -> QByteArray
        """
        Return the toolbox state (as a `QByteArray`).

        .. note:: Individual tabs are stored by their action's text.

        """
        version = 2

        actions = map(self.tabAction, range(self.count()))
        expanded = [action for action in actions if action.isChecked()]
        expanded = [action.text() for action in expanded]

        byte_array = QByteArray()
        stream = QDataStream(byte_array, QIODevice.WriteOnly)
        stream.writeInt(version)
        stream.writeQStringList(expanded)

        return byte_array
Пример #18
0
    def saveGeometryAndLayoutState(self):
        # type: () -> QByteArray
        """
        Save the current geometry and layout state of this widget and
        child windows (if applicable).

        Returns
        -------
        state : QByteArray
            Saved state.
        """
        version = 0x1
        have_spliter = 0
        splitter_state = 0
        if self.__splitter is not None:
            have_spliter = 1
            splitter_state = 1 if self.controlAreaVisible else 0
        data = QByteArray()
        stream = QDataStream(data, QBuffer.WriteOnly)
        stream.writeUInt32(version)
        stream.writeUInt16((have_spliter << 1) | splitter_state)
        stream << self.saveGeometry()
        return data
Пример #19
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)
Пример #20
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)