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)
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
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
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)
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()
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
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
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()
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)
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')))
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
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))
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")))
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")))
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
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
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)
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)