示例#1
0
    def __init__(self, parent=None):
        super(CameraPlugin, self).__init__(parent=parent)

        self._layout = QtWidgets.QHBoxLayout()
        self._layout.setContentsMargins(5, 0, 5, 0)
        self.setLayout(self._layout)

        self.cameras = QtWidgets.QComboBox()
        self.cameras.setMinimumWidth(200)

        self.get_active = QtWidgets.QPushButton("Get active")
        self.get_active.setToolTip("Set camera from currently active view")
        self.refresh = QtWidgets.QPushButton("Refresh")
        self.refresh.setToolTip("Refresh the list of cameras")

        self._layout.addWidget(self.cameras)
        self._layout.addWidget(self.get_active)
        self._layout.addWidget(self.refresh)

        # Signals
        self.get_active.clicked.connect(self.set_active_cam)
        self.refresh.clicked.connect(self.on_refresh)

        self.cameras.currentIndexChanged.connect(self.options_changed)
        self.options_changed.connect(self.on_update_label)

        # Force update of the label
        self.set_active_cam()
        self.on_update_label()
示例#2
0
    def __init__(self, parent=None):
        super(DisplayPlugin, self).__init__(parent=parent)

        self._colors = dict()

        self._layout = QtWidgets.QVBoxLayout()
        self._layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self._layout)

        self.override = QtWidgets.QCheckBox("Override Display Options")

        self.display_type = QtWidgets.QComboBox()
        self.display_type.addItems(["Solid", "Gradient"])

        # create color columns
        self._color_layout = QtWidgets.QHBoxLayout()
        for label, default in COLORS.items():
            self.add_color_picker(self._color_layout, label, default)

        # populate layout
        self._layout.addWidget(self.override)
        self._layout.addWidget(self.display_type)
        self._layout.addLayout(self._color_layout)

        # ensure widgets are in the correct enable state
        self.on_toggle_override()

        self.connections()
示例#3
0
    def __init__(self, parent=None):
        super(CodecPlugin, self).__init__(parent=parent)

        self._layout = QtWidgets.QHBoxLayout()
        self._layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self._layout)

        self.format = QtWidgets.QComboBox()
        self.compression = QtWidgets.QComboBox()
        self.quality = QtWidgets.QSpinBox()
        self.quality.setMinimum(0)
        self.quality.setMaximum(100)
        self.quality.setValue(100)
        self.quality.setToolTip("Compression quality percentage")

        self._layout.addWidget(self.format)
        self._layout.addWidget(self.compression)
        self._layout.addWidget(self.quality)

        self.format.currentIndexChanged.connect(self.on_format_changed)

        self.refresh()

        # Default to format 'qt'
        index = self.format.findText("qt")
        if index != -1:
            self.format.setCurrentIndex(index)

            # Default to compression 'H.264'
            index = self.compression.findText("H.264")
            if index != -1:
                self.compression.setCurrentIndex(index)

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

        self.show_types_list = list()
        self.plugin_shapes = lib.get_plugin_shapes()

        self.setObjectName(self.label)

        self._layout = QtWidgets.QVBoxLayout()
        self._layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self._layout)
        self.override_viewport = QtWidgets.QCheckBox("Override viewport "
                                                     "settings")
        self.override_viewport.setChecked(True)

        # region Show
        self.show_types_button = QtWidgets.QPushButton("Show")
        self.show_types_button.setFixedWidth(150)
        self.show_types_menu = self._build_show_menu()
        self.show_types_button.setMenu(self.show_types_menu)
        # endregion Show

        # region Checkboxes
        self.high_quality = QtWidgets.QCheckBox()
        self.high_quality.setText("Force Viewport 2.0 + AA")
        # endregion Checkboxes

        self._layout.addWidget(self.override_viewport)
        self._layout.addWidget(self.show_types_button)
        self._layout.addWidget(self.high_quality)

        # signals
        self.high_quality.stateChanged.connect(self.options_changed)
        self.override_viewport.stateChanged.connect(self.options_changed)
        self.override_viewport.stateChanged.connect(self.on_toggle_override)
示例#5
0
    def add_color_picker(self, layout, label, default):
        """Create a column with a label and a button to select a color

        Arguments:
            layout (QtWidgets.QLayout): Layout to add color picker to
            label (str): system name for the color type, e.g. : backgroundTop
            default (list): The default color values to start with

        Returns:
            colorpicker.ColorPicker: a color picker instance

        """

        column = QtWidgets.QVBoxLayout()
        label_widget = QtWidgets.QLabel(LABELS[label])

        color_picker = colorpicker.ColorPicker()
        color_picker.color = default

        column.addWidget(label_widget)
        column.addWidget(color_picker)

        column.setAlignment(label_widget, QtCore.Qt.AlignCenter)

        layout.addLayout(column)

        # connect signal
        color_picker.valueChanged.connect(self.options_changed)

        # store widget
        self._colors[label] = color_picker

        return color_picker
示例#6
0
    def __init__(self, parent=None):
        super(TimePlugin, self).__init__(parent=parent)

        self._event_callbacks = list()

        self._layout = QtWidgets.QHBoxLayout()
        self._layout.setContentsMargins(5, 0, 5, 0)
        self.setLayout(self._layout)

        self.mode = QtWidgets.QComboBox()
        self.mode.addItems(
            [self.RangeTimeSlider, self.RangeStartEnd, self.CurrentFrame])

        self.start = QtWidgets.QSpinBox()
        self.start.setRange(-sys.maxint, sys.maxint)
        self.end = QtWidgets.QSpinBox()
        self.end.setRange(-sys.maxint, sys.maxint)

        self._layout.addWidget(self.mode)
        self._layout.addWidget(self.start)
        self._layout.addWidget(self.end)

        self.on_mode_changed()  # force enabled state refresh

        self.mode.currentIndexChanged.connect(self.on_mode_changed)
        self.start.valueChanged.connect(self.on_mode_changed)
        self.end.valueChanged.connect(self.on_mode_changed)
示例#7
0
    def _build_show_menu(self):
        """Build the menu to select which object types are shown in the output.

        Returns:
            QtGui.QMenu: The visibilities "show" menu.

        """

        menu = QtWidgets.QMenu(self)
        menu.setObjectName("ShowShapesMenu")
        menu.setWindowTitle("Show")
        menu.setFixedWidth(180)
        menu.setTearOffEnabled(True)

        # Show all check
        toggle_all = QtWidgets.QAction(menu, text="All")
        toggle_none = QtWidgets.QAction(menu, text="None")
        menu.addAction(toggle_all)
        menu.addAction(toggle_none)
        menu.addSeparator()

        # add plugin shapes if any
        for shape in self.show_types:
            action = QtWidgets.QAction(menu, text=shape)
            action.setCheckable(True)
            # emit signal when the state is changed of the checkbox
            action.toggled.connect(self.options_changed)
            menu.addAction(action)
            self.show_type_actions.append(action)

        # connect signals
        toggle_all.triggered.connect(self.toggle_all_visbile)
        toggle_none.triggered.connect(self.toggle_all_hide)

        return menu
示例#8
0
    def __init__(self, parent=None):
        super(PanZoomPlugin, self).__init__(parent=parent)

        self._layout = QtWidgets.QHBoxLayout()
        self._layout.setContentsMargins(5, 0, 5, 0)
        self.setLayout(self._layout)

        self.pan_zoom = QtWidgets.QCheckBox("Use pan/zoom from camera")
        self.pan_zoom.setChecked(True)

        self._layout.addWidget(self.pan_zoom)

        self.pan_zoom.stateChanged.connect(self.options_changed)
    def _build_show_menu(self):
        """Build the menu to select which object types are shown in the output.
        
        Returns:
            QtGui.QMenu: The visibilities "show" menu.
            
        """

        menu = QtWidgets.QMenu(self)
        menu.setObjectName("ShowShapesMenu")
        menu.setWindowTitle("Show")
        menu.setFixedWidth(150)
        menu.setTearOffEnabled(True)

        # Show all check
        toggle_all = QtWidgets.QAction(menu, text="All")
        toggle_none = QtWidgets.QAction(menu, text="None")
        menu.addAction(toggle_all)
        menu.addAction(toggle_none)
        menu.addSeparator()

        # add standard object shapes
        for obj_type in OBJECT_TYPES.keys():
            action = QtWidgets.QAction(menu, text=obj_type)
            action.setCheckable(True)

            # Add to menu and list of instances
            menu.addAction(action)
            self.show_types_list.append(action)

        menu.addSeparator()

        # add plugin shapes if any
        plugin_shapes = self.plugin_shapes.keys()
        if plugin_shapes:
            for plugin_shape in plugin_shapes:
                action = QtWidgets.QAction(menu, text=plugin_shape)
                action.setCheckable(True)

                menu.addAction(action)
                self.show_types_list.append(action)

        # connect signals
        toggle_all.triggered.connect(self.toggle_all_visbile)
        toggle_none.triggered.connect(self.toggle_all_hide)

        return menu
    def __init__(self, parent=None):
        super(RendererPlugin, self).__init__(parent=parent)

        layout = QtWidgets.QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        # Get active renderers for viewport
        self._renderers = self.get_renderers()

        # Create list of renderers
        self.renderers = QtWidgets.QComboBox()
        self.renderers.addItems(self._renderers.keys())

        layout.addWidget(self.renderers)

        self.apply_inputs(self.get_defaults())
示例#11
0
    def __init__(self, parent=None):
        super(TimePlugin, self).__init__(parent=parent)

        self._event_callbacks = list()

        self._layout = QtWidgets.QHBoxLayout()
        self._layout.setContentsMargins(5, 0, 5, 0)
        self.setLayout(self._layout)

        self.mode = QtWidgets.QComboBox()
        self.mode.addItems([self.RangeTimeSlider,
                            self.RangeStartEnd,
                            self.CurrentFrame,
                            self.CustomFrames])

        frame_input_height = 20
        self.start = QtWidgets.QSpinBox()
        self.start.setRange(-sys.maxint, sys.maxint)
        self.start.setFixedHeight(frame_input_height)
        self.end = QtWidgets.QSpinBox()
        self.end.setRange(-sys.maxint, sys.maxint)
        self.end.setFixedHeight(frame_input_height)

        # unique frames field
        self.custom_frames = QtWidgets.QLineEdit()
        self.custom_frames.setFixedHeight(frame_input_height)
        self.custom_frames.setPlaceholderText("Example: 1-20,25;50;75,100-150")
        self.custom_frames.setVisible(False)

        self._layout.addWidget(self.mode)
        self._layout.addWidget(self.start)
        self._layout.addWidget(self.end)
        self._layout.addWidget(self.custom_frames)

        # Connect callbacks to ensure start is never higher then end
        # and the end is never lower than start
        self.end.valueChanged.connect(self._ensure_start)
        self.start.valueChanged.connect(self._ensure_end)

        self.on_mode_changed()  # force enabled state refresh

        self.mode.currentIndexChanged.connect(self.on_mode_changed)
        self.start.valueChanged.connect(self.on_mode_changed)
        self.end.valueChanged.connect(self.on_mode_changed)
        self.custom_frames.textChanged.connect(self.on_mode_changed)
示例#12
0
    def token_menu(self):
        """
        Build the token menu based on the registered tokens

        :returns: Menu
        :rtype: QtWidgets.QMenu
        """
        menu = QtWidgets.QMenu(self)
        registered_tokens = tokens.list_tokens()

        for token, value in registered_tokens.items():
            label = "{} \t{}".format(token, value['label'])
            action = QtWidgets.QAction(label, menu)
            fn = partial(self.file_path.insert, token)
            action.triggered.connect(fn)
            menu.addAction(action)

        return menu
    def __init__(self, parent=None):
        super(GenericPlugin, self).__init__(parent=parent)

        layout = QtWidgets.QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        isolate_view = QtWidgets.QCheckBox(
            "Use isolate view from active panel")
        off_screen = QtWidgets.QCheckBox("Render offscreen")

        layout.addWidget(isolate_view)
        layout.addWidget(off_screen)

        isolate_view.stateChanged.connect(self.options_changed)
        off_screen.stateChanged.connect(self.options_changed)

        self.widgets = {"off_screen": off_screen, "isolate_view": isolate_view}

        self.apply_inputs(self.get_defaults())
    def add_color_picker(self, layout, label, default):
        """Create a column with a label and a button to select a color
        
        :param layout: the layout to add the color picket too
        :type layout: QtWidgets.QLayout
        
        :param label: the system name for the color type, e.g. : backgroundTop
        :type label: str
        
        :param default: the default color combination to start with
        :type default: list
        
        :return: a color picker instance
        :rtype: colorpicker.ColorPicker
        """

        column = QtWidgets.QVBoxLayout()
        label_widget = QtWidgets.QLabel(LABELS[label])

        color_picker = colorpicker.ColorPicker()
        color_picker.color = default

        column.addWidget(label_widget)
        column.addWidget(color_picker)

        column.setAlignment(label_widget, QtCore.Qt.AlignCenter)

        layout.addLayout(column)

        # connect signal
        color_picker.valueChanged.connect(self.options_changed)

        # store widget
        self._colors[label] = color_picker

        return color_picker
示例#15
0
    def __init__(self, parent, filepath):
        super(IoAction, self).__init__(parent)

        action_label = os.path.basename(filepath)

        self.setText(action_label)
        self.setData(filepath)

        # check if file exists and disable when false
        self.setEnabled(os.path.isfile(filepath))

        # get icon from file
        info = QtCore.QFileInfo(filepath)
        icon_provider = QtWidgets.QFileIconProvider()
        self.setIcon(icon_provider.icon(info))

        self.triggered.connect(self.open_object_data)
示例#16
0
    def _build_light_menu(self):
        """Build lighting menu.

        Create the menu items for the different types of lighting for
        in the viewport

        Returns:
            None

        """

        menu = QtWidgets.QComboBox(self)

        # names cane be found in
        display_lights = (("Use Default Lighting",
                           "default"), ("Use All Lights", "all"),
                          ("Use Selected Lights",
                           "active"), ("Use Flat Lighting",
                                       "flat"), ("Use No Lights", "none"))

        for label, name in display_lights:
            menu.addItem(label, userData=name)

        return menu
示例#17
0
    def __init__(self, parent=None):
        super(ViewportPlugin, self).__init__(parent=parent)

        # set inherited attributes
        self.setObjectName(self.label)

        # custom atttributes
        self.show_type_actions = list()

        # get information
        self.show_types = lib.get_show_object_types()

        # set main layout for widget
        self._layout = QtWidgets.QVBoxLayout()
        self._layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self._layout)

        # build
        # region Menus
        menus_vlayout = QtWidgets.QHBoxLayout()

        # Display Lights
        self.display_light_menu = self._build_light_menu()
        self.display_light_menu.setFixedHeight(20)

        # Show
        self.show_types_button = QtWidgets.QPushButton("Show")
        self.show_types_button.setFixedHeight(20)
        self.show_types_menu = self._build_show_menu()
        self.show_types_button.setMenu(self.show_types_menu)

        # fill layout
        menus_vlayout.addWidget(self.display_light_menu)
        menus_vlayout.addWidget(self.show_types_button)

        # endregion Menus

        # region Checkboxes
        checkbox_layout = QtWidgets.QGridLayout()
        self.high_quality = QtWidgets.QCheckBox()
        self.high_quality.setText("Force Viewport 2.0 + AA")
        self.override_viewport = QtWidgets.QCheckBox("Override viewport "
                                                     "settings")
        self.override_viewport.setChecked(True)

        # two sided lighting
        self.two_sided_ligthing = QtWidgets.QCheckBox("Two Sided Ligthing")
        self.two_sided_ligthing.setChecked(False)

        # show
        self.shadows = QtWidgets.QCheckBox("Shadows")
        self.shadows.setChecked(False)

        checkbox_layout.addWidget(self.override_viewport, 0, 0)
        checkbox_layout.addWidget(self.high_quality, 0, 1)
        checkbox_layout.addWidget(self.two_sided_ligthing, 1, 0)
        checkbox_layout.addWidget(self.shadows, 1, 1)
        # endregion Checkboxes

        self._layout.addLayout(checkbox_layout)
        self._layout.addLayout(menus_vlayout)

        self.connections()
示例#18
0
    def __init__(self, parent=None):
        super(ResolutionPlugin, self).__init__(parent=parent)

        self._layout = QtWidgets.QVBoxLayout()
        self._layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self._layout)

        # Scale
        self.mode = QtWidgets.QComboBox()
        self.mode.addItems(
            [self.ScaleWindow, self.ScaleRenderSettings, self.ScaleCustom])
        self.mode.setCurrentIndex(1)  # Default: From render settings

        # Custom width/height
        self.resolution = QtWidgets.QWidget()
        self.resolution.setContentsMargins(0, 0, 0, 0)
        resolution_layout = QtWidgets.QHBoxLayout()
        resolution_layout.setContentsMargins(0, 0, 0, 0)
        resolution_layout.setSpacing(6)

        self.resolution.setLayout(resolution_layout)
        width_label = QtWidgets.QLabel("Width")
        width_label.setFixedWidth(40)
        self.width = QtWidgets.QSpinBox()
        self.width.setMinimum(0)
        self.width.setMaximum(99999)
        self.width.setValue(1920)
        heigth_label = QtWidgets.QLabel("Height")
        heigth_label.setFixedWidth(40)
        self.height = QtWidgets.QSpinBox()
        self.height.setMinimum(0)
        self.height.setMaximum(99999)
        self.height.setValue(1080)

        resolution_layout.addWidget(width_label)
        resolution_layout.addWidget(self.width)
        resolution_layout.addWidget(heigth_label)
        resolution_layout.addWidget(self.height)

        self.scale_result = QtWidgets.QLineEdit()
        self.scale_result.setReadOnly(True)

        # Percentage
        self.percent_label = QtWidgets.QLabel("Scale")
        self.percent = QtWidgets.QDoubleSpinBox()
        self.percent.setMinimum(0.01)
        self.percent.setValue(1.0)  # default value
        self.percent.setSingleStep(0.05)

        self.percent_presets = QtWidgets.QHBoxLayout()
        self.percent_presets.setSpacing(4)
        for value in [0.25, 0.5, 0.75, 1.0, 2.0]:
            btn = QtWidgets.QPushButton(str(value))
            self.percent_presets.addWidget(btn)
            btn.setFixedWidth(35)
            btn.clicked.connect(partial(self.percent.setValue, value))

        self.percent_layout = QtWidgets.QHBoxLayout()
        self.percent_layout.addWidget(self.percent_label)
        self.percent_layout.addWidget(self.percent)
        self.percent_layout.addLayout(self.percent_presets)

        # Resulting scale display
        self._layout.addWidget(self.mode)
        self._layout.addWidget(self.resolution)
        self._layout.addLayout(self.percent_layout)
        self._layout.addWidget(self.scale_result)

        # refresh states
        self.on_mode_changed()
        self.on_resolution_changed()

        # connect signals
        self.mode.currentIndexChanged.connect(self.on_mode_changed)
        self.mode.currentIndexChanged.connect(self.on_resolution_changed)
        self.percent.valueChanged.connect(self.on_resolution_changed)
        self.width.valueChanged.connect(self.on_resolution_changed)
        self.height.valueChanged.connect(self.on_resolution_changed)

        # Connect options changed
        self.mode.currentIndexChanged.connect(self.options_changed)
        self.percent.valueChanged.connect(self.options_changed)
        self.width.valueChanged.connect(self.options_changed)
        self.height.valueChanged.connect(self.options_changed)
示例#19
0
    def __init__(self, parent=None):
        super(IoPlugin, self).__init__(parent=parent)

        self.recent_playblasts = list()

        self._layout = QtWidgets.QVBoxLayout()
        self._layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self._layout)

        # region Checkboxes
        checkbox_hlayout = QtWidgets.QHBoxLayout()
        checkbox_hlayout.setContentsMargins(5, 0, 5, 0)
        self.save_file = QtWidgets.QCheckBox(text="Save")
        self.use_default = QtWidgets.QCheckBox(text="Use Default")
        self.open_viewer = QtWidgets.QCheckBox(text="View when finished")
        checkbox_hlayout.addWidget(self.save_file)
        checkbox_hlayout.addWidget(self.use_default)
        checkbox_hlayout.addWidget(self.open_viewer)
        checkbox_hlayout.addStretch(True)
        # endregion Checkboxes

        # region Directory
        self.dir_widget = QtWidgets.QWidget()
        dir_hlayout = QtWidgets.QHBoxLayout()
        dir_hlayout.setContentsMargins(0, 0, 0, 0)
        dir_label = QtWidgets.QLabel("Directory :")
        dir_label.setFixedWidth(60)
        self.browse = QtWidgets.QPushButton("Browse")
        self.directory_path = QtWidgets.QLineEdit()
        self.directory_path.setPlaceholderText("Select a directory")
        dir_hlayout.addWidget(dir_label)
        dir_hlayout.addWidget(self.directory_path)
        dir_hlayout.addWidget(self.browse)
        self.dir_widget.setLayout(dir_hlayout)
        # endregion Directory

        # region Filename
        self.filename_widget = QtWidgets.QWidget()
        filename_hlayout = QtWidgets.QHBoxLayout()
        filename_hlayout.setContentsMargins(0, 0, 0, 0)
        filename_label = QtWidgets.QLabel("File Name :")
        filename_label.setFixedWidth(60)
        self.filename = QtWidgets.QLineEdit()
        filename_hlayout.addWidget(filename_label)
        filename_hlayout.addWidget(self.filename)
        self.filename_widget.setLayout(filename_hlayout)
        # endregion Filename

        # region Recent Playblast
        self.play_recent = QtWidgets.QPushButton("Play recent playblast")
        self.recent_menu = QtWidgets.QMenu()
        self.play_recent.setMenu(self.recent_menu)
        # endregion Recent Playblast

        self._layout.addLayout(checkbox_hlayout)
        self._layout.addWidget(self.filename_widget)
        self._layout.addWidget(self.dir_widget)
        self._layout.addWidget(self.play_recent)

        self.browse.clicked.connect(self.get_save_directory)
        self.use_default.stateChanged.connect(self.toggle_use_default)
        self.save_file.stateChanged.connect(self.toggle_save)

        # set state of save widgets
        self.toggle_save()
        self.toggle_use_default()
示例#20
0
    def __init__(self, parent=None):
        super(IoPlugin, self).__init__(parent=parent)

        self.recent_playblasts = list()

        self._layout = QtWidgets.QVBoxLayout()
        self._layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self._layout)

        # region Checkboxes
        self.save_file = QtWidgets.QCheckBox(text="Save")
        self.open_viewer = QtWidgets.QCheckBox(text="View when finished")
        self.raw_frame_numbers = QtWidgets.QCheckBox(text="Raw frame numbers")

        checkbox_hlayout = QtWidgets.QHBoxLayout()
        checkbox_hlayout.setContentsMargins(5, 0, 5, 0)
        checkbox_hlayout.addWidget(self.save_file)
        checkbox_hlayout.addWidget(self.open_viewer)
        checkbox_hlayout.addWidget(self.raw_frame_numbers)
        checkbox_hlayout.addStretch(True)
        # endregion Checkboxes

        # region Path
        self.path_widget = QtWidgets.QWidget()

        self.browse = QtWidgets.QPushButton("Browse")
        self.file_path = QtWidgets.QLineEdit()
        self.file_path.setPlaceholderText("(not set; using scene name)")
        tip = "Right click in the text field to insert tokens"
        self.file_path.setToolTip(tip)
        self.file_path.setStatusTip(tip)
        self.file_path.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.file_path.customContextMenuRequested.connect(self.show_token_menu)

        path_hlayout = QtWidgets.QHBoxLayout()
        path_hlayout.setContentsMargins(0, 0, 0, 0)
        path_label = QtWidgets.QLabel("Path:")
        path_label.setFixedWidth(30)

        path_hlayout.addWidget(path_label)
        path_hlayout.addWidget(self.file_path)
        path_hlayout.addWidget(self.browse)
        self.path_widget.setLayout(path_hlayout)
        # endregion Path

        # region Recent Playblast
        self.play_recent = QtWidgets.QPushButton("Play recent playblast")
        self.recent_menu = QtWidgets.QMenu()
        self.play_recent.setMenu(self.recent_menu)
        # endregion Recent Playblast

        self._layout.addLayout(checkbox_hlayout)
        self._layout.addWidget(self.path_widget)
        self._layout.addWidget(self.play_recent)

        # Signals  / connections
        self.browse.clicked.connect(self.show_browse_dialog)
        self.file_path.textChanged.connect(self.options_changed)
        self.save_file.stateChanged.connect(self.options_changed)
        self.raw_frame_numbers.stateChanged.connect(self.options_changed)
        self.save_file.stateChanged.connect(self.on_save_changed)

        # Ensure state is up-to-date with current settings
        self.on_save_changed()