Пример #1
0
class PlotPygal(QDialog):
    def __init__(self, live=False):
        super().__init__()

        self.live = live

        self.setWindowTitle('Saved session plotted with Pygal')
        self.setWindowIcon(QtGui.QIcon('icons/pulse.svg'))

        self.webW = QWebEngineView()

        self.saveButton = QtGui.QPushButton(self)
        self.saveButton.setText('Save as SVG')
        self.saveButton.clicked.connect(self.saveSVG)

        self.verticalLayout = QtGui.QVBoxLayout(self)
        self.verticalLayout.addWidget(self.webW)
        self.verticalLayout.addWidget(self.saveButton)

        self.plotPygal()

    def plotPygal(self):
        w.oxi.plot_pygal(live=self.live)

        self.webW.setContent(w.oxi.chart, mimeType='image/svg+xml')
        self.show()

    def saveSVG(self):
        filename = QFileDialog.getSaveFileName(self)[0]
        if filename:
            print(filename)
            w.oxi.write_svg(filename)
        else:
            print('No file selected')
class PlotPygal(QDialog):
    def __init__(self, live=False):
        super().__init__()
        
        self.live = live
        
        self.setWindowTitle('Saved session plotted with Pygal')
        self.setWindowIcon(QtGui.QIcon('icons/pulse.svg')) 
        
        self.webW = QWebEngineView()
        
        self.saveButton = QtGui.QPushButton(self)
        self.saveButton.setText('Save as SVG')
        self.saveButton.clicked.connect(self.saveSVG)
        
        self.verticalLayout = QtGui.QVBoxLayout(self)
        self.verticalLayout.addWidget(self.webW)
        self.verticalLayout.addWidget(self.saveButton)
        
        self.plotPygal()
        
    def plotPygal(self):
        w.oxi.plot_pygal(live=self.live)
        
        size = sys.getsizeof(w.oxi.chart)
        if size > 2097152: # QWebEngineView can only directly display sizes up to 2 MiB
                           # https://bugreports.qt.io/browse/QTBUG-53414
                           # (I'm just assuming MiB, not MB.)
            self.webW.setHtml('<p><center><big><b>The plot is too large to be displayed within this window. Save the file first and view it in a viewer of your choice.</b></big></center></p>')
        else:
            self.webW.setContent(w.oxi.chart, mimeType='image/svg+xml')
        self.show()
        
    def saveSVG(self):
        filename = QFileDialog.getSaveFileName(self)[0]
        if filename:
            print(filename)
            w.oxi.write_svg(filename)
        else:
            print('No file selected')
Пример #3
0
class Tab(QWidget):
    currItemChanged = pyqtSignal(['QModelIndex'])

    def __init__(self, packItem=QModelIndex(), parent: TabWidget = None):
        super(Tab, self).__init__(parent)
        self.tabWidget = parent
        self.icon = QIcon()
        self.initActions()

        self.pathToolBar = ToolBar(self)
        self.pathToolBar.addAction(self.backAct)
        self.pathToolBar.addAction(self.forwardAct)

        self.pathLine: AddressLine = AddressLine(self)
        self.objTypeLine = LineEdit(self, placeholderText="Object Type")
        self.objTypeLine.setFixedWidth(168)
        self.objTypeLine.setReadOnly(True)

        self.descrLabel = QLabel(self)
        self.descrLabel.setWordWrap(True)
        self.descrLabel.setTextInteractionFlags(Qt.TextSelectableByMouse)

        QWebEngineSettings.defaultSettings().setAttribute(
            QWebEngineSettings.PluginsEnabled, True)
        self.mediaWidget = QWebEngineView()
        self.saveMediaAsBtn = QPushButton(
            f"Save media as..",
            self,
            toolTip="Save media file as..",
            clicked=lambda: self.saveMediaAsWithDialog(
                QStandardPaths.writableLocation(QStandardPaths.
                                                DocumentsLocation)))
        self.saveMediaBtn = QPushButton(
            f"Save media on desktop",
            self,
            toolTip="Save media file on desktop",
            clicked=lambda: self.saveMediaAsWithDialog(
                QStandardPaths.writableLocation(QStandardPaths.DesktopLocation)
            ))
        self.mediaViewWidget = QWidget()
        mediaViewWidgetLayout = QVBoxLayout(self.mediaViewWidget)
        mediaViewWidgetLayout.setContentsMargins(0, 0, 0, 0)
        mediaViewWidgetLayout.addWidget(self.mediaWidget)
        mediaViewWidgetLayout.addWidget(self.saveMediaBtn)
        mediaViewWidgetLayout.addWidget(self.saveMediaAsBtn)
        self.mediaViewWidget.hide()

        self.attrsTreeView = AttrsTreeView(self)
        self.attrsTreeView.setFrameShape(QFrame.NoFrame)

        self.toolBar = ToolBar(self)
        self.toolBar.addAction(self.attrsTreeView.zoomInAct)
        self.toolBar.addAction(self.attrsTreeView.zoomOutAct)
        self.toolBar.addAction(self.attrsTreeView.collapseAllAct)
        self.toolBar.addAction(self.attrsTreeView.expandAllAct)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.attrsTreeView.undoAct)
        self.toolBar.addAction(self.attrsTreeView.redoAct)
        self.toolBar.addAction(self.attrsTreeView.copyAct)
        self.toolBar.addAction(self.attrsTreeView.cutAct)
        self.toolBar.addAction(self.attrsTreeView.pasteAct)
        self.toolBar.addAction(self.attrsTreeView.delClearAct)
        self.toolBar.addAction(self.attrsTreeView.editCreateInDialogAct)
        self.toolBar.addAction(self.attrsTreeView.addAct)
        self.searchBar = SearchBar(
            self.attrsTreeView,
            parent=self,
            filterColumns=[ATTRIBUTE_COLUMN, VALUE_COLUMN],
            closable=True)
        self.searchBar.hide()
        self.openSearchBarSC = QShortcut(SC_SEARCH,
                                         self,
                                         activated=self.openSearchBar)

        self.packItem = QPersistentModelIndex(QModelIndex())
        self.prevItems = []
        self.nextItems = []
        if packItem.isValid():
            self.openItem(packItem)
        else:
            self.openEmptyItem()

        self._initLayout()

    # noinspection PyArgumentList
    def initActions(self):
        self.backAct = QAction(BACK_ICON,
                               "Back",
                               self,
                               statusTip=f"Go back one item",
                               toolTip=f"Go back one item",
                               shortcut=SC_BACK,
                               triggered=self.openPrevItem,
                               enabled=False)

        self.forwardAct = QAction(FORWARD_ICON,
                                  "Forward",
                                  self,
                                  statusTip=f"Go forward one item",
                                  toolTip=f"Go forward one item",
                                  shortcut=SC_FORWARD,
                                  triggered=self.openNextItem,
                                  enabled=False)

    def windowTitle(self) -> str:
        return self.packItem.data(NAME_ROLE)

    def windowIcon(self) -> QIcon:
        return self.packItem.data(Qt.DecorationRole)

    def openSearchBar(self):
        self.searchBar.show()
        self.searchBar.searchLine.setFocus()

    def openItem(self, packItem: QModelIndex):
        if not packItem == QModelIndex(self.packItem):
            self.nextItems.clear()
            if self.packItem.isValid():
                self.prevItems.append(self.packItem)
            self._openItem(packItem)

    def openPrevItem(self):
        if self.prevItems:
            prevItem = self.prevItems.pop()
            self.nextItems.append(self.packItem)
            self._openItem(QModelIndex(prevItem))

    def openNextItem(self):
        if self.nextItems:
            nextItem = self.nextItems.pop()
            self.prevItems.append(self.packItem)
            self._openItem(QModelIndex(nextItem))

    def openEmptyItem(self):
        self._openItem(QModelIndex())

    def _openItem(self, packItem: QModelIndex):
        try:
            currTab: Tab = self.tabWidget.currentWidget()
            state = currTab.attrsTreeView.header().saveState()
        except AttributeError:
            # if there is no curr widget, there is no current header state, it
            state = None

        self.packItem = QPersistentModelIndex(packItem.siblingAtColumn(0))
        self.descrLabel.setText("")

        self.packItemObj = self.packItem.data(OBJECT_ROLE)
        self.updateMediaWidget()
        self.pathLine.setText(getTreeItemPath(self.packItem))
        self.objTypeLine.setText(getTypeName(type(self.packItemObj)))

        icon = self.packItem.data(Qt.DecorationRole)
        if icon:
            self.setWindowIcon(icon)
        self.setWindowTitle(self.packItem.data(Qt.DisplayRole))
        self.attrsTreeView.newPackItem(self.packItem)
        self.attrsTreeView.selectionModel().currentChanged.connect(
            self.showDetailInfoItemDoc)
        self.currItemChanged.emit(QModelIndex(self.packItem))

        self.forwardAct.setEnabled(
            True) if self.nextItems else self.forwardAct.setDisabled(True)
        self.backAct.setEnabled(
            True) if self.prevItems else self.backAct.setDisabled(True)
        if state:
            self.attrsTreeView.header().restoreState(state)

    def updateMediaWidget(self):
        if self.packItem.data(IS_MEDIA_ROLE):
            self.mediaWidget.setContent(b"loading...")
            self.mediaViewWidget.show()
            if not self.mediaWidget.width():
                # set equal sizes
                oldSizes = self.splitter.sizes()
                newSizes = [
                    sum(oldSizes) / (len(oldSizes)) for size in oldSizes
                ]
                self.splitter.setSizes(newSizes)

            try:
                mediaContent = self.packItem.data(MEDIA_CONTENT_ROLE)
                if self.packItem.data(IS_URL_MEDIA_ROLE):
                    self.mediaWidget.load(QUrl(mediaContent.value))
                else:
                    self.mediaWidget.setContent(mediaContent.value,
                                                mediaContent.mime_type)
            except Exception as e:
                print(e)
                self.mediaWidget.setContent(
                    b"Error occurred while loading media")
            self.mediaWidget.setZoomFactor(1.0)
        else:
            self.mediaViewWidget.hide()

    def saveMediaAsWithDialog(self, directory="") -> bool:
        mediaContent = self.packItem.data(MEDIA_CONTENT_ROLE)
        file = self.packItem.data(NAME_ROLE)
        saved = False
        while not saved:
            try:
                file = QFileDialog.getSaveFileName(
                    self,
                    'Save media File',
                    directory + "/" + file.strip("/"),
                    options=FILE_DIALOG_OPTIONS)[0]
            except AttributeError as e:
                QMessageBox.critical(self, "Error", f"{e}")
            else:
                if file:
                    saved = self.saveMedia(mediaContent, file)
                else:
                    # cancel pressed
                    return

    def saveMedia(self, media=None, file: str = None) -> bool:
        try:
            with open(file, "wb") as f:
                f.write(media.value)
            return True
        except (TypeError, ValueError) as e:
            QMessageBox.critical(self, "Error",
                                 f"Media couldn't be saved: {file}: {e}")
        except AttributeError as e:
            QMessageBox.critical(self, "Error",
                                 f"No chosen media to save: {e}")
        return False

    def showDetailInfoItemDoc(self, detailInfoItem: QModelIndex):
        self.descrLabel.setText(detailInfoItem.data(Qt.WhatsThisRole))

    def _initLayout(self):
        pathWidget = QWidget()
        pathLayout = QHBoxLayout(pathWidget)
        pathLayout.setContentsMargins(0, 0, 0, 0)
        pathLayout.addWidget(self.pathToolBar)
        pathLayout.addWidget(self.pathLine)
        pathLayout.addWidget(self.objTypeLine)
        pathWidget.setFixedHeight(TOOLBARS_HEIGHT)

        toolBarWidget = QWidget()
        toolBarLayout = QHBoxLayout(toolBarWidget)
        toolBarLayout.setContentsMargins(0, 0, 0, 0)
        toolBarLayout.addWidget(self.toolBar)
        toolBarLayout.addWidget(self.searchBar)
        toolBarWidget.setFixedHeight(TOOLBARS_HEIGHT)

        treeViewWidget = QWidget()
        treeViewLayout = QVBoxLayout(treeViewWidget)
        treeViewLayout.setContentsMargins(0, 0, 0, 0)
        treeViewLayout.addWidget(pathWidget)
        treeViewLayout.addWidget(self.attrsTreeView)
        treeViewLayout.addWidget(self.descrLabel)

        self.splitter = QSplitter()
        self.splitter.setOrientation(Qt.Horizontal)
        self.splitter.setContentsMargins(0, 0, 0, 0)
        self.splitter.addWidget(treeViewWidget)
        self.splitter.addWidget(self.mediaViewWidget)

        layout = QVBoxLayout(self)
        layout.setObjectName("tabLayout")
        layout.addWidget(pathWidget)
        layout.addWidget(toolBarWidget)
        layout.addWidget(self.splitter)
        layout.setSpacing(2)
        layout.setContentsMargins(0, 2, 0, 2)