class UIStreamPreviewNode(UINodeBase): def __init__(self, raw_node): super(UIStreamPreviewNode, self).__init__(raw_node) self.resizable = True self.Imagelabel = QLabel("") self.pixmap = QtGui.QPixmap(None) self.addWidget(self.Imagelabel) self.updateSize() def Tick(self, *args, **kwargs): self.updateSize() super(UIStreamPreviewNode, self).Tick(*args, **kwargs) def updateSize(self): if getattr(self._rawNode, 'display_frame', None) is None: return frame = self._rawNode.display_frame.copy() width = int(self.customLayout.geometry().width()) height = int(frame.shape[0] * (width / frame.shape[1])) display_frame = cv2.cvtColor(cv2.resize(frame, (width, height)), cv2.COLOR_BGR2RGB) qImg = QtGui.QImage(display_frame.data, width, height, 3 * width, QtGui.QImage.Format_RGB888) self.pixmap = QtGui.QPixmap(qImg) self.Imagelabel.setPixmap(self.pixmap)
def add_files(self, filenames): """add filenames (list(str)) to the table""" for f in filenames: row = self.table.rowCount() self.table.insertRow(row) file_item = QTableWidgetItem() file_item.setData(Qt.DisplayRole, f) self.table.setItem(row, 0, file_item) widget_that_lets_me_horizontally_align_an_icon = QWidget() widget_layout = QHBoxLayout( widget_that_lets_me_horizontally_align_an_icon) section_remove = QLabel() dim = int(1.5 * section_remove.fontMetrics().boundingRect("Z").height()) section_remove.setPixmap( QIcon(section_remove.style().standardIcon( QStyle.SP_DialogDiscardButton)).pixmap(dim, dim)) widget_layout.addWidget(section_remove, 0, Qt.AlignHCenter) widget_layout.setContentsMargins(0, 0, 0, 0) self.table.setCellWidget( row, 1, widget_that_lets_me_horizontally_align_an_icon) self.add_last_row()
def create_drop_indicator_widget(drop_area): layout = QLabel() layout.setObjectName('DropAreaLabel') metric = (layout.fontMetrics().height()) * 2.0 size = QSizeF(metric, metric) layout.setPixmap( DropOverlay.create_drop_indicator_pixmap(palette=layout.palette(), size=size, drop_area=drop_area)) return layout
def add_ligand(tool): rows = tool.ligand_table.rowCount() if rows != 0: rows -= 1 ligand_name = QTableWidgetItem() name = "<click to choose>" is_c2 = Qt.Unchecked enabled = True if rows > 0: name = tool.ligand_table.item(rows - 1, 0).text() is_c2 = tool.ligand_table.cellWidget(rows - 1, 1).layout().itemAt(0).widget().checkState() enabled = tool.ligand_table.cellWidget(rows - 1, 1).layout().itemAt(0).widget().isEnabled() ligand_name.setData(Qt.DisplayRole, name) tool.ligand_table.setItem(rows, 0, ligand_name) widget_that_lets_me_horizontally_align_a_checkbox = QWidget() widget_layout = QHBoxLayout(widget_that_lets_me_horizontally_align_a_checkbox) c2 = QCheckBox() c2.setEnabled(enabled) c2.setCheckState(is_c2) widget_layout.addWidget(c2, 0, Qt.AlignHCenter) widget_layout.setContentsMargins(0, 0, 0, 0) tool.ligand_table.setCellWidget( rows, 1, widget_that_lets_me_horizontally_align_a_checkbox ) widget_that_lets_me_horizontally_align_an_icon = QWidget() widget_layout = QHBoxLayout(widget_that_lets_me_horizontally_align_an_icon) section_remove = QLabel() dim = int(1.5 * section_remove.fontMetrics().boundingRect("Q").height()) section_remove.setPixmap( QIcon(section_remove.style().standardIcon( QStyle.SP_DialogDiscardButton) ).pixmap(dim, dim) ) widget_layout.addWidget(section_remove, 0, Qt.AlignHCenter) widget_layout.setContentsMargins(0, 0, 0, 0) tool.ligand_table.setCellWidget( rows, 2, widget_that_lets_me_horizontally_align_an_icon ) rows += 1 tool.ligand_table.insertRow(rows) widget_that_lets_me_horizontally_align_an_icon = QWidget() widget_layout = QHBoxLayout(widget_that_lets_me_horizontally_align_an_icon) ligand_add = QLabel("add ligand") widget_layout.addWidget(ligand_add, 0, Qt.AlignHCenter) widget_layout.setContentsMargins(0, 0, 0, 0) tool.ligand_table.setCellWidget(rows, 1, widget_that_lets_me_horizontally_align_an_icon)
class UIStreamPreviewNode(UINodeBase): def __init__(self, raw_node): super(UIStreamPreviewNode, self).__init__(raw_node) self.resizable = True self.Imagelabel = QLabel("test3") self.pixmap = QtGui.QPixmap(None) self.addWidget(self.Imagelabel) self.updateSize() def paint(self, painter, option, widget): self.updateSize() super(UIStreamPreviewNode, self).paint(painter, option, widget) def updateSize(self): self.pixmap = QtGui.QPixmap(self._rawNode.label.getData()) scaledPixmap = self.pixmap.scaledToWidth( self.customLayout.geometry().width()) self.Imagelabel.setPixmap(scaledPixmap)
class UIQimageDisplay(UINodeBase): def __init__(self, raw_node): super(UIQimageDisplay, self).__init__(raw_node) self.resizable = True self.Imagelabel = QLabel("test3") self.pixmap = QtGui.QPixmap(RESOURCES_DIR + "/wizard-cat.png") self.addWidget(self.Imagelabel) self.updateSize() self._rawNode.loadImage.connect(self.onLoadImage) def onLoadImage(self, imagePath): self.pixmap = QtGui.QPixmap(imagePath) self.updateSize() def paint(self, painter, option, widget): self.updateSize() super(UIQimageDisplay, self).paint(painter, option, widget) def updateSize(self): scaledPixmap = self.pixmap.scaledToWidth( self.customLayout.geometry().width()) self.Imagelabel.setPixmap(scaledPixmap)
def __init__(self, name, report, parent=None): QDialog.__init__(self, parent) icon = self.style().standardIcon(QStyle.SP_MessageBoxCritical) self.setWindowTitle('Error reporting') self.setWindowIcon(icon) try: font = QFontDatabase().systemFont(QFontDatabase.FixedFont) except AttributeError as e: font = QFont() font.setStyleHint(QFont.TypeWriter) self.text = QPlainTextEdit() self.text.setFont(font) self.text.setReadOnly(True) self.text.setLineWrapMode(QPlainTextEdit.NoWrap) self.text.setPlainText(report) TracebackHighlighter(self.text.document()) icon_label = QLabel() icon_label.setPixmap(icon.pixmap(ICON_SIZE, ICON_SIZE)) label = QLabel("{} error !".format(name)) label.setFont(QFont('default', pointSize=14)) button_copy = QPushButton('Copy to clipboard') button_copy.clicked.connect(self._copy) layout = QGridLayout(self) layout.addWidget(icon_label, 0, 0) layout.addWidget(label, 0, 1) layout.addWidget(self.text, 1, 0, 1, 2) layout.addWidget(button_copy, 2, 0, 1, 2) layout.setColumnStretch(1, 100) self.setModal(True) self.resize(600, 400)
class NotificationPopup(QWidget): def __init__(self, parent=None): super().__init__(parent) self.m_icon = QLabel() self.m_title = QLabel() self.m_message = QLabel() self.notification = None self.setWindowFlags(Qt.ToolTip) rootLayout = QHBoxLayout(self) rootLayout.addWidget(self.m_icon) bodyLayout = QVBoxLayout() rootLayout.addLayout(bodyLayout) titleLayout = QHBoxLayout() bodyLayout.addLayout(titleLayout) titleLayout.addWidget(self.m_title) titleLayout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding)) close = QPushButton(self.tr("Close")) titleLayout.addWidget(close) close.clicked.connect(self.onClosed) bodyLayout.addWidget(self.m_message) self.adjustSize() def present(self, newNotification): if self.notification: self.notification.close() sip.delete(self.notification) self.notification = None self.notification = newNotification self.m_title.setText(f"<b>{self.notification.title()}</b>") self.m_message.setText(self.notification.message()) self.m_icon.setPixmap( QPixmap.fromImage(self.notification.icon()).scaledToHeight( self.m_icon.height())) self.show() self.notification.show() self.notification.closed.connect(self.onClosed) QTimer.singleShot( 10000, lambda: self.onClosed() if self.notification is not None else None) # position our popup in the right corner of its parent widget self.move(self.parentWidget().mapToGlobal( self.parentWidget().rect().bottomRight() - QPoint(self.width() + 10, self.height() + 10))) @Slot() def onClosed(self): self.hide() self.notification.close() self.notification = None def mouseReleaseEvent(self, event): super().mouseReleaseEvent(event) if self.notification and event.button() == Qt.LeftButton: self.notification.click() self.onClosed()
class ProjectSettingsWidget(base.BaseWidget, object): exitSettings = Signal() def __init__(self, project=None, parent=None): self._project = None super(ProjectSettingsWidget, self).__init__(parent=parent) self._fill_version_types_combo() if project: self.set_project(project) def ui(self): super(ProjectSettingsWidget, self).ui() image_layout = layouts.HorizontalLayout(spacing=2, margins=(2, 2, 2, 2)) image_layout.setContentsMargins(2, 2, 2, 2) image_layout.setSpacing(2) self.main_layout.addLayout(image_layout) self._project_image = QLabel() self._project_image.setAlignment(Qt.AlignCenter) image_layout.addStretch() image_layout.addWidget(self._project_image) image_layout.addStretch() self._settings_tab = tabs.BaseTabWidget(parent=self) self.main_layout.addWidget(self._settings_tab) self._naming_widget = NamingWidget(project=self._project) self._project_options_widget = rigoptionsviewer.RigOptionsViewer( option_object=self._project, parent=self) self._external_code_widget = ExternalCodeDirectoryWidget(parent=self) version_control_widget = QWidget(parent=self) version_control_layout = layouts.VerticalLayout(spacing=0, margins=(2, 2, 2, 2)) version_control_widget.setLayout(version_control_layout) self._version_type_combo = combobox.BaseComboBox(parent=self) version_control_layout.addWidget(self._version_type_combo) version_control_layout.addStretch() self._settings_tab.addTab(self._project_options_widget, 'Settings') self._settings_tab.addTab(self._naming_widget, 'Nomenclature') self._settings_tab.addTab(version_control_widget, 'Version Control') self._settings_tab.addTab(self._external_code_widget, 'External Code') bottom_layout = layouts.VerticalLayout(spacing=2, margins=(2, 2, 2, 2)) bottom_layout.setAlignment(Qt.AlignBottom) self.main_layout.addLayout(bottom_layout) bottom_layout.addLayout(dividers.DividerLayout()) buttons_layout = layouts.HorizontalLayout(spacing=2, margins=(2, 2, 2, 2)) bottom_layout.addLayout(buttons_layout) ok_icon = resources.icon('ok') self._ok_btn = buttons.BaseButton(parent=self) self._ok_btn.setIcon(ok_icon) buttons_layout.addWidget(self._ok_btn) def setup_signals(self): self._version_type_combo.currentIndexChanged.connect( self._on_version_control_type_changed) self._ok_btn.clicked.connect(self._on_exit) def get_project(self): """ Returns current RigBuilder project used by this widget :return: Project """ return self._project def set_project(self, project): """ Sets current project used by this widget :param project: Project """ self._project = project self._project_options_widget.set_option_object(self._project) if self._project: self._project_image.setPixmap( QPixmap(self._project.get_project_image()).scaled( QSize(150, 150), Qt.KeepAspectRatio)) self._naming_widget.set_project(self._project) self._external_code_widget.set_project(self._project) if self._project and self._project.settings.has_setting( 'version_control'): try: version_control_index = int( self._project.settings.has_setting('version_control')) except Exception: version_control_index = 0 self._version_type_combo.setCurrentIndex(version_control_index) def update_options(self, do_reload=False): """ Update options of the current project """ if not self._project: return if do_reload: self._project.reload_options() self._project_options_widget.update_options() def _fill_version_types_combo(self): """ Internal callback function that fills with the different types of supported version controls """ self._version_type_combo.clear() for version_type in ['none', 'git']: self._version_type_combo.addItem(resources.icon(version_type), version_type) def _on_version_control_type_changed(self, index): """ Internal callback function that is called when version control type is updated :param index: int :return: """ if not self._project: return self._project.settings.set('version_control', int(index)) def _on_exit(self): """ Internal callback function that is called when the user exists settings widget """ self.exitSettings.emit()
class UIOpenCvBaseNode(UINodeBase): def __init__(self, raw_node): super(UIOpenCvBaseNode, self).__init__(raw_node) self.imagePin = self._rawNode.getPinByName("img") if not self.imagePin: for pin in self._rawNode.outputs.values(): if pin.dataType == "ImagePin": self.imagePin = pin break if self.imagePin: self.actionViewImage = self._menu.addAction("ViewImage") self.actionViewImage.triggered.connect(self.viewImage) self.actionViewImage.setData( NodeActionButtonInfo( os.path.dirname(__file__) + "/resources/ojo.svg", ViewImageNodeActionButton)) self.actionRefreshImage = self._menu.addAction( "RefreshCurrentNode") self.actionRefreshImage.triggered.connect(self.refreshImage) self.actionRefreshImage.setData( NodeActionButtonInfo( os.path.dirname(__file__) + "/resources/reload.svg", NodeActionButtonBase)) self.displayImage = False self.resizable = True self.Imagelabel = QLabel("noImage") self.pixmap = QtGui.QPixmap() self.addWidget(self.Imagelabel) self.Imagelabel.setVisible(False) self.updateSize() self._rawNode.computed.connect(self.updateImage) @property def collapsed(self): return self._collapsed @collapsed.setter def collapsed(self, bCollapsed): if bCollapsed != self._collapsed: self._collapsed = bCollapsed self.aboutToCollapse(self._collapsed) for i in range(0, self.inputsLayout.count()): inp = self.inputsLayout.itemAt(i) inp.setVisible(not bCollapsed) for o in range(0, self.outputsLayout.count()): out = self.outputsLayout.itemAt(o) out.setVisible(not bCollapsed) for cust in range(0, self.customLayout.count()): out = self.customLayout.itemAt(cust) out.setVisible(not bCollapsed) if not self.displayImage: self.Imagelabel.setVisible(False) self.updateNodeShape() def updateImage(self, *args, **kwargs): if self.displayImage and not self.collapsed: if self.imagePin: img = self.imagePin.getData() self.setNumpyArray(img.image) def refreshImage(self): if self.imagePin: self._rawNode.processNode() if self.displayImage and not self.collapsed: if self.imagePin: img = self.imagePin.getData() self.setNumpyArray(img.image) self.Imagelabel.setVisible(True) else: self.Imagelabel.setVisible(False) def viewImage(self): self.displayImage = not self.displayImage self.refreshImage() self.updateNodeShape() self.updateSize() def setNumpyArray(self, image): if image.__class__.__name__ == "UMat": image = cv2.UMat.get(image) image = toQImage(image) self.pixmap = QtGui.QPixmap.fromImage(image, QtCore.Qt.ThresholdAlphaDither) self.updateSize() def paint(self, painter, option, widget): self.updateSize() super(UIOpenCvBaseNode, self).paint(painter, option, widget) def updateSize(self): if not self.pixmap.isNull(): scaledPixmap = self.pixmap.scaledToWidth( self.customLayout.geometry().width()) self.Imagelabel.setMaximumWidth( self.customLayout.geometry().width()) self.Imagelabel.setPixmap(scaledPixmap) def updateNodeShape(self): super(UIOpenCvBaseNode, self).updateNodeShape() self.updateSize() self.update()
class MetaCard(base.BaseWidget, object): def __init__(self, extra=False, parent=None): self._extra = extra super(MetaCard, self).__init__(parent=parent) self.setAttribute(Qt.WA_StyledBackground) # ================================================================================================================= # OVERRIDES # ================================================================================================================= def get_main_layout(self): main_layout = layouts.VerticalLayout(spacing=0, margins=(1, 1, 1, 1)) return main_layout def ui(self): super(MetaCard, self).ui() self._title_layout = layouts.HorizontalLayout() self._cover_label = QLabel() self._cover_label.setFixedSize(QSize(200, 200)) self._avatar = avatar.Avatar() self._title_label = label.BaseLabel().h4() self._description_label = label.BaseLabel().secondary() self._description_label.setWordWrap(True) self._description_label.theme_elide_mode = Qt.ElideRight self._extra_btn = buttons.BaseToolButton( parent=self).image('more').icon_only() self._title_layout.addWidget(self._title_label) self._title_layout.addStretch() self._title_layout.addWidget(self._extra_btn) self._extra_btn.setVisible(self._extra) content_lyt = layouts.FormLayout(margins=(5, 5, 5, 5)) content_lyt.addRow(self._avatar, self._title_layout) content_lyt.addRow(self._description_label) self._btn_lyt = layouts.HorizontalLayout() self.main_layout.addWidget(self._cover_label) self.main_layout.addLayout(content_lyt) self.main_layout.addLayout(self._btn_lyt) self.main_layout.addStretch() # ================================================================================================================= # BASE # ================================================================================================================= def get_more_button(self): """ Returns more button :return: buttons.BaseToolButton """ return self._extra_button def setup_data(self, data_dict): if data_dict.get('title'): self._title_label.setText(data_dict.get('title')) self._title_label.setVisible(True) else: self._title_label.setVisible(False) if data_dict.get('description'): self._description_label.setText(data_dict.get('description')) self._description_label.setVisible(True) else: self._description_label.setVisible(False) if data_dict.get('avatar'): self._avatar.image = data_dict.get('avatar') self._avatar.setVisible(True) else: self._avatar.setVisible(False) if data_dict.get('cover'): fixed_height = self._cover_label.width() self._cover_label.setPixmap( data_dict.get('cover').scaledToWidth(fixed_height, Qt.SmoothTransformation)) self._cover_label.setVisible(True) else: self._cover_label.setVisible(False)
class DockTitleBar(QWidget, object): def __init__(self, dock_widget, renamable=False): super(DockTitleBar, self).__init__(dock_widget) self._renamable = renamable main_layout = layouts.HorizontalLayout(margins=(0, 0, 0, 1)) self.setLayout(main_layout) self._buttons_box = QGroupBox('') self._buttons_box.setObjectName('Docked') self._buttons_layout = layouts.HorizontalLayout(spacing=1, margins=(2, 2, 2, 2)) self._buttons_box.setLayout(self._buttons_layout) main_layout.addWidget(self._buttons_box) self._icon_label = QLabel(self) self._title_label = QLabel(self) self._title_label.setStyleSheet('background: transparent') self._title_edit = QLineEdit(self) self._title_edit.setVisible(False) self._button_size = QSize(14, 14) self._dock_btn = QToolButton(self) self._dock_btn.setIcon(resources.icon('restore_window', theme='color')) self._dock_btn.setMaximumSize(self._button_size) self._dock_btn.setAutoRaise(True) self._close_btn = QToolButton(self) self._close_btn.setIcon(resources.icon('close_window', theme='color')) self._close_btn.setMaximumSize(self._button_size) self._close_btn.setAutoRaise(True) self._buttons_layout.addSpacing(2) self._buttons_layout.addWidget(self._icon_label) self._buttons_layout.addWidget(self._title_label) self._buttons_layout.addWidget(self._title_edit) self._buttons_layout.addStretch() self._buttons_layout.addSpacing(5) self._buttons_layout.addWidget(self._dock_btn) self._buttons_layout.addWidget(self._close_btn) self._buttons_box.mouseDoubleClickEvent = self.mouseDoubleClickEvent self._buttons_box.mousePressEvent = self.mousePressEvent self._buttons_box.mouseMoveEvent = self.mouseMoveEvent self._buttons_box.mouseReleaseEvent = self.mouseReleaseEvent dock_widget.featuresChanged.connect(self._on_dock_features_changed) self._title_edit.editingFinished.connect(self._on_finish_edit) self._dock_btn.clicked.connect(self._on_dock_btn_clicked) self._close_btn.clicked.connect(self._on_close_btn_clicked) self._on_dock_features_changed(dock_widget.features()) self.set_title(dock_widget.windowTitle()) dock_widget.installEventFilter(self) dock_widget.topLevelChanged.connect(self._on_change_floating_style) if hasattr(dock_widget, 'icon') and callable(dock_widget.icon): self._icon_label.setPixmap(dock_widget.icon().pixmap(QSize(16, 16))) @property def renamable(self): return self._renamable @renamable.setter def renamable(self, flag): self._renamable = flag def eventFilter(self, obj, event): try: if event.type() == QEvent.WindowTitleChange: self.set_title(obj.windowTitle()) return super(DockTitleBar, self).eventFilter(obj, event) except Exception as exc: event.accept() return True def mouseMoveEvent(self, event): event.ignore() def mousePressEvent(self, event): event.ignore() def mouseReleaseEvent(self, event): event.ignore() def mouseDoubleClickEvent(self, event): if event.pos().x() <= self._title_label.width() and self._renamable: self._start_edit() else: super(DockTitleBar, self).mouseDoubleClickEvent(event) def update(self, *args, **kwargs): self._on_change_floating_style(self.parent().isFloating()) super(DockTitleBar, self).update(*args, **kwargs) def set_title(self, title): self._title_label.setText(title) self._title_edit.setText(title) def add_button(self, button): button.setAutoRaise(True) button.setMaximumSize(self._button_size) self._buttons_layout.insertWidget(5, button) def _start_edit(self): self._title_label.hide() self._title_edit.show() self._title_edit.setFocus() def _finish_edit(self): self._title_edit.hide() self._title_label.show() self.parent().setWindowTitle(self._title_edit.text()) def _on_dock_features_changed(self, features): if not features & QDockWidget.DockWidgetVerticalTitleBar: self._close_btn.setVisible(features & QDockWidget.DockWidgetClosable) self._dock_btn.setVisible(features & QDockWidget.DockWidgetFloatable) else: raise ValueError('Vertical title bar is not supported!') def _on_finish_edit(self): self._finish_edit() def _on_dock_btn_clicked(self): self.parent().setFloating(not self.parent().isFloating()) def _on_close_btn_clicked(self): self.parent().toggleViewAction().setChecked(False) self.parent().close() def _on_change_floating_style(self, state): pass
class BaseSaveWidget(base.BaseWidget, object): def __init__(self, item, settings, temp_path=None, parent=None): # self._item = None self._settings = settings self._temp_path = temp_path self._options_widget = None # super(BaseSaveWidget, self).__init__(parent=parent) # # self.setObjectName('LibrarySaveWidget') # self.set_item(item) def ui(self): super(BaseSaveWidget, self).ui() title_layout = layouts.HorizontalLayout() title_layout.setContentsMargins(2, 2, 0, 0) title_layout.setSpacing(2) self._icon_lbl = QLabel() self._icon_lbl.setMaximumSize(QSize(14, 14)) self._icon_lbl.setMinimumSize(QSize(14, 14)) self._icon_lbl.setScaledContents(True) self._title_lbl = QLabel() title_layout.addWidget(self._icon_lbl) title_layout.addWidget(self._title_lbl) self._folder_widget = directory.SelectFolder('Folder', use_app_browser=True) buttons_layout = layouts.HorizontalLayout() buttons_layout.setContentsMargins(4, 4, 4, 4) buttons_layout.setSpacing(4) buttons_frame = QFrame() buttons_frame.setFrameShape(QFrame.NoFrame) buttons_frame.setFrameShadow(QFrame.Plain) buttons_frame.setLayout(buttons_layout) buttons_layout.addStretch() self.save_btn = buttons.BaseButton('Save') self.cancel_btn = buttons.BaseButton('Cancel') buttons_layout.addWidget(self.save_btn, parent=self) buttons_layout.addWidget(self.cancel_btn, parent=self) buttons_layout.addStretch() self._options_layout = layouts.VerticalLayout() self._options_layout.setContentsMargins(0, 0, 0, 0) self._options_layout.setSpacing(2) self._options_frame = QFrame() self._options_frame.setFrameShape(QFrame.NoFrame) self._options_frame.setFrameShadow(QFrame.Plain) self._options_frame.setLineWidth(0) self._options_frame.setLayout(self._options_layout) self._extra_layout = layouts.VerticalLayout() self._extra_layout.setContentsMargins(0, 0, 0, 0) self._extra_layout.setSpacing(2) self.main_layout.addLayout(title_layout) self.main_layout.addWidget(self._folder_widget) self._extra_layout.addWidget(self._options_frame) self.main_layout.addWidget(dividers.Divider()) self.main_layout.addLayout(self._extra_layout) self.main_layout.addWidget(dividers.Divider()) self.main_layout.addWidget(buttons_frame) def setup_signals(self): self.save_btn.clicked.connect(self._on_save) self.cancel_btn.clicked.connect(self._on_cancel) def settings(self): """ Returns settings object :return: JSONSettings """ return self._settings def set_settings(self, settings): """ Sets save widget settings :param settings: JSONSettings """ self._settings = settings # def item(self): # """ # Returns the library item to be created # :return: LibraryItem # """ # # return self._item def set_item(self, item): """ Sets the base item to be created :param item: LibraryItem """ self._item = item self._title_lbl.setText(item.MenuName) self._icon_lbl.setPixmap(QPixmap(item.type_icon_path())) schema = item.save_schema() if schema: options_widget = formwidget.FormWidget(self) options_widget.set_schema(schema) options_widget.set_validator(item.save_validator) self._options_frame.layout().addWidget(options_widget) self._options_widget = options_widget self.load_settings() options_widget.stateChanged.connect(self._on_options_changed) options_widget.validate() else: self._options_frame.setVisible(False) def library_window(self): """ Returns library widget window for the item :return: LibraryWindow """ return self._item.library_window() def set_library_window(self, library_window): """ Sets the library widget for the item :param library_window: LibraryWindow """ self._item.set_library_window(library_window) def name(self): """ Returns the name of the field :return: str """ return self._title_lbl.text().strip() def description(self): """ Returns the string from the comment field :return: str """ return self._comment.toPlainText().strip() def folder_frame(self): """ Returns the frame that contains the folder edit, label and button :return: QFrame """ return self._folder_frame def folder_path(self): """ Returns the folder path :return: str """ return self._folder_widget.folder_line.text() def set_folder_path(self, path): """ Sets the destination folder path :param path: str """ self._folder_widget.folder_line.setText(path) def default_values(self): """ Returns all the default values for the save fields :return: dict """ values = dict() for option in self.item().save_schema(): values[option.get('name')] = option.get('default') return values def save_settings(self): """ Saves the current state of the widget to disk """ state = self._options_widget.options_state() self.settings().set(self.item().__class__.__name__, {'SaveOptions': state}) def load_settings(self): """ Returns the settings object for saving the state of the widget """ option_settings = self.settings().get(self.item().__class__.__name__, {}) options = option_settings.get('SaveOptions', dict()) values = self.default_values() if options: for option in self.item().save_schema(): name = option.get('name') persistent = option.get('persistent') if not persistent and name in options: options[name] = values[name] self._options_widget.set_state_from_options(options) def save(self, path, icon_path, objects=None): """ Saves the item with the given objects to the given disk location path :param path: list(str) :param icon_path: str :param objects: str """ item = self.item() options = self._options_widget.values() item.save(path=path, objects=objects, icon_path=icon_path, **options) self.close() def _save(self): if not self.library_window(): return try: path = self.folder_path() options = self._options_widget.values() name = options.get('name') objects = dcc.selected_nodes(full_path=True) or list() if not path: raise Exception( 'No folder selected. Please select a destination folder') if not name: raise Exception( 'No name specified. Please set a name before saving') if not os.path.exists(self.icon_path()): btn = self.show_thumbnail_capture_dialog() if btn == QDialogButtonBox.Cancel: return path += '/{}'.format(name) icon_path = self.icon_path() self.save(path=path, icon_path=icon_path, objects=objects) except Exception as e: messagebox.MessageBox.critical(self.library_window(), 'Error while saving', str(e)) LOGGER.error(traceback.format_exc()) raise self.library_window().stack.slide_in_index(0) def _on_options_changed(self): """ Internal callback function that is called when an option value changes """ self.save_settings() def _on_save(self): if not self.library_window(): return self._save() self.library_window().stack.slide_in_index(0) def _on_cancel(self): self.close() self.library_window().stack.slide_in_index(0)