コード例 #1
0
class PenSetWidget(QWidget):

    penSizeTrigger = Signal(int)
    penColorTrigger = Signal(str)
    fontChangeTrigger = Signal(QFont)

    def __init__(self, parent=None):
        super(PenSetWidget, self).__init__(parent)

        self.paddingX = 5
        self.paddingY = 2
        self.iconWidth = self.iconHeight = 24
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
        self.setWindowFlags(Qt.ToolTip)

        self.initWindows()

        self.prevSizeButton = self.penSize1
        self.penSize1.setChecked(True)
        self.presentColor.setStyleSheet(
            'QPushButton { background-color: %s; }' % PENCOLOR)

    def generateButtons(self, parent=None):
        """ Generate buttons due to colorDic """
        self.colorButtons = []
        for color in self.colorList:
            button = QPushButton(parent)
            button.setObjectName(color[0])
            button.setStyleSheet('QPushButton { background-color: %s; }' %
                                 color[1])
            button.setFixedSize(self.iconWidth / 2, self.iconHeight / 2)
            button.setCheckable(True)
            self.colorButtons.append(button)

    def initWindows(self):
        self.mainLayout = QHBoxLayout()
        self.setLayout(self.mainLayout)
        self.mainLayout.setSpacing(0)
        self.mainLayout.setContentsMargins(5, 2, 5, 2)

        self.initPenSizeButtons()
        self.initFontWidget()
        self.initPenColorButtons()

        self.separator = QFrame(self)
        self.separator.setFrameShape(QFrame.VLine)
        self.separator.setFrameShadow(QFrame.Sunken)

        self.mainLayout.addWidget(self.penSize)
        self.mainLayout.addWidget(self.changeFontButton)
        self.mainLayout.addWidget(self.separator)

        self.mainLayout.addWidget(self.colorSet)

    def initPenSizeButtons(self):
        self.penSize = QWidget(self)
        self.penSizeLayout = QHBoxLayout()
        self.penSize.setLayout(self.penSizeLayout)
        # adjust pen size
        self.penSize1 = QPushButton(self.penSize)
        self.penSize1.setIcon(QIcon(":/resource/icon/pensize1.png"))
        self.penSize1.setObjectName('1')
        self.penSize1.setFixedSize(self.iconWidth, self.iconHeight)
        self.penSize1.setCheckable(True)

        self.penSize2 = QPushButton(self.penSize)
        self.penSize2.setIcon(QIcon(":/resource/icon/pensize2.png"))
        self.penSize2.setObjectName('2')
        self.penSize2.setFixedSize(self.iconWidth, self.iconHeight)
        self.penSize2.setCheckable(True)

        self.penSize3 = QPushButton(self.penSize)
        self.penSize3.setIcon(QIcon(":/resource/icon/pensize3.png"))
        self.penSize3.setObjectName('3')
        self.penSize3.setFixedSize(self.iconWidth, self.iconHeight)
        self.penSize3.setCheckable(True)

        self.sizeButtonGroup = QButtonGroup(self.penSize)
        self.sizeButtonGroup.addButton(self.penSize1)
        self.sizeButtonGroup.addButton(self.penSize2)
        self.sizeButtonGroup.addButton(self.penSize3)
        self.sizeButtonGroup.buttonClicked.connect(self.sizeButtonToggled)

        self.penSizeLayout.addWidget(self.penSize1)
        self.penSizeLayout.addWidget(self.penSize2)
        self.penSizeLayout.addWidget(self.penSize3)

        self.penSizeLayout.setSpacing(5)
        self.penSizeLayout.setContentsMargins(0, 0, 0, 0)

    def initPenColorButtons(self):
        self.colorSet = QWidget(self)
        self.colorLayout = QHBoxLayout()
        self.colorLayout.setSpacing(5)
        self.colorLayout.setContentsMargins(5, 0, 5, 0)
        self.colorSet.setLayout(self.colorLayout)

        self.presentColor = QPushButton(self.colorSet)
        self.presentColor.setFixedSize(self.iconWidth, self.iconHeight)
        self.presentColor.setEnabled(False)

        # adjust pen color

        self.colorPick = QWidget(self.colorSet)
        self.colorGrid = QGridLayout()
        self.colorGrid.setSpacing(0)
        self.colorGrid.setContentsMargins(5, 0, 5, 0)
        self.colorPick.setLayout(self.colorGrid)

        self.colorList = [('white', '#ffffff'), ('red', '#ff0000'),
                          ('green', '#00ff00'), ('blue', '#0000ff'),
                          ('cyan', '#00ffff'), ('magenta', '#ff00ff'),
                          ('yellow', '#ffff00'), ('gray', '#a0a0a4'),
                          ('black', '#000000'), ('darkRed', '#800000'),
                          ('darkGreen', '#008000'), ('darkBlue', '#000080'),
                          ('darkCyan', '#008080'), ('darkMagenta', '#800080'),
                          ('darkYellow', '#808000'), ('darkGray', '#808080')]

        self.generateButtons()

        self.colorButtonGroup = QButtonGroup(self)
        for button in self.colorButtons:
            self.colorButtonGroup.addButton(button)
        self.colorButtonGroup.buttonClicked.connect(self.colorButtonToggled)

        # set the layout
        tmp = 0
        for x in range(0, 2):
            for y in range(0, int(len(self.colorList) / 2)):
                self.colorGrid.addWidget(self.colorButtons[tmp], x, y)
                tmp += 1

        self.colorGrid.setSpacing(0)
        self.colorGrid.setContentsMargins(0, 0, 0, 0)

        self.colorLayout.addWidget(self.presentColor)
        self.colorLayout.addWidget(self.colorPick)

    def initFontWidget(self):
        self.fontDialog = QFontDialog()
        self.changeFontButton = QPushButton(self)
        self.fontDialog.setCurrentFont(QFont('Sans serif'))
        self.changeFontButton.setText('{0} {1}'.format(
            self.fontDialog.currentFont().family(),
            self.fontDialog.currentFont().pointSize()))
        self.changeFontButton.clicked.connect(self.fontButtonClicked)

    def showFontWidget(self):
        self.changeFontButton.show()
        self.penSize1.hide()
        self.penSize2.hide()
        self.penSize3.hide()

    def showPenWidget(self):
        self.changeFontButton.hide()
        self.penSize1.show()
        self.penSize2.show()
        self.penSize3.show()

    # slots
    def colorButtonToggled(self, button):
        self.presentColor.setStyleSheet(
            'QPushButton { background-color: %s; }' % button.objectName())
        self.penColorTrigger.emit(button.objectName())

    def sizeButtonToggled(self, button):
        self.penSizeTrigger.emit(int(button.objectName()) * 2)

    def fontButtonClicked(self):
        ok = True
        font = QFontDialog.getFont(self)
        if font[1]:
            self.changeFontButton.setText('{0} {1}'.format(
                font[0].family(), font[0].pointSize()))
            self.fontChangeTrigger.emit(font[0])
コード例 #2
0
class SaveWidget(BaseSaveWidget, object):
    def __init__(self, item, settings, temp_path=None, parent=None):

        self._script_job = None
        self._sequence_path = None
        self._icon_path = ''

        super(SaveWidget, self).__init__(item=item,
                                         settings=settings,
                                         temp_path=temp_path,
                                         parent=parent)

        self.create_sequence_widget()
        self.update_thumbnail_size()

        try:
            self._on_selection_changed()
            # self.set_script_job_enabled(True)
        except NameError as e:
            LOGGER.error('{} | {}'.format(e, traceback.format_exc()))

    def ui(self):
        super(SaveWidget, self).ui()

        model_panel_layout = layouts.HorizontalLayout()
        model_panel_layout.setContentsMargins(0, 0, 0, 0)
        model_panel_layout.setSpacing(0)
        thumbnail_layout = layouts.VerticalLayout()
        thumbnail_layout.setContentsMargins(0, 0, 0, 0)
        thumbnail_layout.setSpacing(0)
        self._thumbnail_frame = QFrame()
        self._thumbnail_frame.setMinimumSize(QSize(50, 50))
        self._thumbnail_frame.setMaximumSize(QSize(150, 150))
        self._thumbnail_frame.setSizePolicy(QSizePolicy.Expanding,
                                            QSizePolicy.Expanding)
        self._thumbnail_frame.setFrameShape(QFrame.NoFrame)
        self._thumbnail_frame.setFrameShadow(QFrame.Plain)
        self._thumbnail_frame.setLineWidth(0)
        self._thumbnail_frame.setLayout(thumbnail_layout)
        model_panel_layout.addWidget(self._thumbnail_frame)
        self._thumbnail_btn = QPushButton()
        self._thumbnail_btn.setMinimumSize(QSize(0, 0))
        self._thumbnail_btn.setSizePolicy(QSizePolicy.Expanding,
                                          QSizePolicy.Expanding)
        self._thumbnail_btn.setMaximumSize(QSize(150, 150))
        self._thumbnail_btn.setToolTip('Take snapshot')
        self._thumbnail_btn.setStyleSheet(
            'color: rgb(40, 40, 40);border: 0px solid rgb(0, 0, 0, 150);background-color: rgb(254, 255, 230, 200);'
        )
        self._thumbnail_btn.setIcon(resources.icon('thumbnail'))
        self._thumbnail_btn.setToolTip("""
        Click to capture a thumbnail from the current viewport.\n
        CTRL + Click to show the capture window for better framing
        """)
        thumbnail_layout.addWidget(self._thumbnail_btn)

        self._extra_layout.addLayout(model_panel_layout)

    def setup_signals(self):
        super(SaveWidget, self).setup_signals()
        self._thumbnail_btn.clicked.connect(self._on_thumbnail_capture)

    def resizeEvent(self, event):
        """
        Overrides base QWidget resizeEvent function
        :param event: QResizeEvent
        """

        self.update_thumbnail_size()

    def icon_path(self):
        """
        Returns the icon path to be used for the thumbnail
        :return: str
        """

        return self._icon_path

    def set_icon(self, icon):
        """
        Sets the icon for the create widget thumbnail
        :param icon: QIcon
        """

        self._thumbnail_btn.setIcon(icon)
        self._thumbnail_btn.setIconSize(QSize(200, 200))
        self._thumbnail_btn.setText('')

    def sequence_path(self):
        """
        Returns the playblast path
        :return: str
        """

        return self._sequence_path

    def set_sequence_path(self, path):
        """
        Sets the disk location for the image sequence to be saved
        :param path: str
        """

        self._sequence_path = path
        self._thumbnail_btn.set_dirname(os.path.dirname(path))

    def create_sequence_widget(self):
        """
        Creates a sequence widget to replace the static thumbnail widget
        """

        sequence_widget = widgets.LibraryImageSequenceWidget(self)
        sequence_widget.setObjectName('thumbnailButton')
        sequence_widget.setStyleSheet(self._thumbnail_btn.styleSheet())
        sequence_widget.setToolTip(self._thumbnail_btn.toolTip())

        camera_icon = resources.get('icons', 'camera.svg')
        expand_icon = resources.get('icons', 'expand.svg')
        folder_icon = resources.get('icons', 'folder.svg')

        sequence_widget.addAction(camera_icon, 'Capture new image',
                                  'Capture new image',
                                  self._on_thumbnail_capture)
        sequence_widget.addAction(expand_icon, 'Show Capture window',
                                  'Show Capture window',
                                  self._on_show_capture_window)
        sequence_widget.addAction(folder_icon, 'Load image from disk',
                                  'Load image from disk',
                                  self._on_show_browse_image_dialog)

        sequence_widget.setIcon(resources.icon('thumbnail2'))
        self._thumbnail_frame.layout().insertWidget(0, sequence_widget)
        self._thumbnail_btn.hide()
        self._thumbnail_btn = sequence_widget
        self._thumbnail_btn.clicked.connect(self._on_thumbnail_capture)

    def set_sequence(self, source):
        """
        Sets the sequenced path for the thumbnail widget
        :param source: str
        """

        self.set_thumbnail(source, sequence=True)

    def set_thumbnail(self, source, sequence=False):
        """
        Sets the thumbnail
        :param source: str
        :param sequence: bool
        """

        source = os.path.normpath(source)

        # TODO: Find a way to remove temp folder afteer saving the file
        # filename, extension = os.path.splitext(source)
        # with path_utils.temp_dir() as dir_path:
        # dir_path = path_utils.temp_dir()
        # target = os.path.join(dir_path, 'thumbnail{}'.format(extension))
        # shutil.copyfile(source, target)
        # tpQtLib.logger.debug('Source Thumbnail: {}'.format(source))
        # tpQtLib.logger.debug('Target Thumbnail: {}'.format(target))
        # self._icon_path = target
        # self._thumbnail_btn.set_path(target)

        self._icon_path = source
        self._thumbnail_btn.set_path(source)

        if sequence:
            self.set_sequence_path(source)

    def update_thumbnail_size(self):
        """
        Updates the thumbnail button to teh size of the widget
        """

        width = self.width() - 10
        if width > 250:
            width = 250
        size = QSize(width, width)
        self._thumbnail_btn.setIconSize(size)
        self._thumbnail_btn.setMaximumSize(size)
        self._thumbnail_frame.setMaximumSize(size)

    def show_by_frame_dialog(self):
        """
        Show the by frame dialog
        """

        help_text = """
        To help speed up the playblast you can set the "by frame" to another greather than 1.
        For example if the "by frame" is set to 2 it will playblast every second frame
        """

        options = self._options_widget.values()
        by_frame = options.get('byFrame', 1)
        start_frame, end_frame = options.get('frameRange', [None, None])
        duration = 1
        if start_frame is not None and end_frame is not None:
            duration = end_frame - start_frame
        if duration > 100 and by_frame == 1:
            buttons = QDialogButtonBox.Ok | QDialogButtonBox.Cancel
            result = messagebox.MessageBox.question(
                self.library_window(),
                title='Tip',
                text=help_text,
                buttons=buttons,
                enable_dont_show_checkbox=True)
            if result != QDialogButtonBox.Ok:
                raise Exception('Cancelled by user')

    def show_thumbnail_capture_dialog(self):
        """
        Asks the user if they would like to capture a thumbnail
        :return: int
        """

        buttons = QDialogButtonBox.Yes | QDialogButtonBox.Ignore | QDialogButtonBox.Cancel
        parent = self.item().library_window()
        btn = messagebox.MessageBox.question(
            None,
            'Create a thumbnail',
            'Would you like to capture a thumbnail?',
            buttons=buttons)
        if btn == QDialogButtonBox.Yes:
            self.thumbnail_capture()

        return btn

    def thumbnail_capture(self, show=False):
        """
        Captures a playblast and saves it to the temporal thumbnail path
        :param show: bool
        """

        options = self._options_widget.values()
        start_frame, end_frame = options.get('frameRange', [None, None])
        step = options.get('byFrame', 1)

        if not qtutils.is_control_modifier():
            self.show_by_frame_dialog()

        if not self._temp_path or not os.path.isdir(self._temp_path):
            self._temp_path = tempfile.mkdtemp()
        self._temp_path = os.path.join(self._temp_path, 'thumbnail.jpg')

        try:
            snapshot.SnapshotWindow(path=self._temp_path,
                                    on_save=self._on_thumbnail_captured)
            # thumbnail.ThumbnailCaptureDialog.thumbnail_capture(
            #     path=self._temp_path,
            #     show=show,
            #     start_frame=start_frame,
            #     end_frame=end_frame,
            #     step=step,
            #     clear_cache=False,
            #     captured=self._on_thumbnail_captured
            # )
        except Exception as e:
            messagebox.MessageBox.critical(self.library_window(),
                                           'Error while capturing thumbnail',
                                           str(e))
            LOGGER.error(traceback.format_exc())

    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()
        sequence_path = self.sequence_path()
        if sequence_path:
            sequence_path = os.path.dirname(sequence_path)

        item.save(path=path,
                  objects=objects,
                  icon_path=icon_path,
                  sequence_path=sequence_path,
                  **options)

        self.close()

    def _on_selection_changed(self):
        """
        Internal callback functino that is called when DCC selection changes
        """

        if self._options_widget:
            self._options_widget.validate()

    def _on_thumbnail_capture(self):
        self.thumbnail_capture(show=False)

    def _on_thumbnail_captured(self, captured_path):
        """
        Internal callback function that is called when thumbnail is captured
        :param captured_path: str
        """

        self.set_sequence(captured_path)

    def _on_show_capture_window(self):
        """
        Internal callback function that shows the capture window for framing
        """

        self.thumbnail_capture(show=True)

    def _on_show_browse_image_dialog(self):
        """
        Internal callback function that shows a file dialog for choosing an image from disk
        """

        file_dialog = QFileDialog(self,
                                  caption='Open Image',
                                  filter='Image Files (*.png *.jpg)')
        file_dialog.fileSelected.connect(self.set_thumbnail)
        file_dialog.exec_()