def paintEvent(self, event): """ Render the UI. """ if self._mode == self.MODE_OFF: return painter = QtGui.QPainter() painter.begin(self) try: # set up semi transparent backdrop painter.setRenderHint(QtGui.QPainter.Antialiasing) overlay_color = QtGui.QColor(30, 30, 30, 100) painter.setBrush( QtGui.QBrush(overlay_color)) painter.setPen(QtGui.QPen(overlay_color)) painter.drawRect(0, 0, painter.device().width(), painter.device().height()) # show the spinner painter.translate((painter.device().width() / 2) - 10, (painter.device().height() / 2) - 10) pen = QtGui.QPen(QtGui.QColor(self._bundle.style_constants["SG_HIGHLIGHT_COLOR"])) pen.setWidth(1) painter.setPen(pen) r = QtCore.QRectF(0.0, 0.0, 20.0, 20.0) start_angle = (0 + self._spin_angle) * 4 * 16 span_angle = 340 * 16 painter.drawArc(r, start_angle, span_angle) finally: painter.end()
def paintEvent(self, paint_event): """ Paint Event override """ # paint multiple values indicator if self._multiple_values == True: p = QtGui.QPainter(self) p.drawPixmap( 0, 0, self.width(), self.height(), self._no_thumb_pixmap, 0, 0, self._no_thumb_pixmap.width(), self._no_thumb_pixmap.height(), ) p.fillRect(0, 0, self.width(), self.height(), QtGui.QColor(42, 42, 42, 237)) p.setFont(QtGui.QFont("Arial", 15, QtGui.QFont.Bold)) pen = QtGui.QPen(QtGui.QColor("#18A7E3")) p.setPen(pen) p.drawText(self.rect(), QtCore.Qt.AlignCenter, "Multiple Values") else: # paint thumbnail QtGui.QLabel.paintEvent(self, paint_event)
def _style(self, style_type): palette = self._palette styles = { "keyword": _format( colorize(palette.windowText().color(), 3, QtGui.QColor(0, 0, 255), 1), style="", ), "builtin": _format( colorize(palette.windowText().color(), 3, QtGui.QColor(0, 255, 0), 1), style="", ), "operator": _format( colorize( palette.windowText().color(), 4, palette.highlight().color(), 2 ), style="", ), "brace": _format( colorize(palette.windowText().color(), 2, palette.base().color(), 1), style="bold", ), "defclass": _format( colorize(palette.windowText().color(), 3, QtGui.QColor(255, 0, 0), 1), style="bold", ), "string": _format( colorize( palette.windowText().color(), 2, palette.highlight().color(), 1 ), style="bold", ), "string2": _format( colorize(palette.windowText().color(), 1, palette.base().color(), 1), style="", ), "comment": _format( colorize(palette.windowText().color(), 1, palette.base().color(), 2), style="italic", ), "self": _format( colorize( palette.windowText().color(), 1, QtGui.QColor(127, 127, 127), 1 ), style="", ), "numbers": _format( colorize( palette.windowText().color(), 3, QtGui.QColor(127, 127, 127), 1 ), style="", ), } return styles[style_type]
def __init__(self, icon_label, status_label, progress_bar): """ :param parent: The model parent. :type parent: :class:`~PySide.QtGui.QObject` """ super(ProgressHandler, self).__init__() self._icon_label = icon_label self._status_label = status_label self._progress_bar = progress_bar self._icon_lookup = { self.PHASE_LOAD: QtGui.QPixmap(":/tk_multi_publish2/status_load.png"), self.PHASE_VALIDATE: QtGui.QPixmap(":/tk_multi_publish2/status_validate.png"), self.PHASE_PUBLISH: QtGui.QPixmap(":/tk_multi_publish2/status_publish.png"), self.PHASE_FINALIZE: QtGui.QPixmap(":/tk_multi_publish2/status_success.png"), } self._icon_warning = QtGui.QPixmap( ":/tk_multi_publish2/status_warning.png") self._icon_error = QtGui.QPixmap( ":/tk_multi_publish2/status_error.png") # These colors come from the HIG. self._debug_brush = QtGui.QBrush(QtGui.QColor("#88BC47")) # green self._warning_brush = QtGui.QBrush(QtGui.QColor("#F9A332")) # orange self._error_brush = QtGui.QBrush(QtGui.QColor("#EC494A")) # red # parent our progress widget overlay self._progress_details = ProgressDetailsWidget( self._progress_bar.parent()) self._progress_details.copy_to_clipboard_clicked.connect( self._copy_log_to_clipboard) # clicking on the log toggles the logging window self._status_label.clicked.connect(self._progress_details.toggle) # store all log messages in a list self._log_messages = [] self._current_indent = 0 # set up our log dispatch self._log_wrapper = PublishLogWrapper(self) self._logging_parent_item = None # none means root self._current_phase = None
def paintEvent(self, event): """ Handles painting the text fade overlay. Overrides the same method from ``QtGui.QWidget`` """ painter = QtGui.QPainter(self) # calculate the rectangle to paint the overlay. # it should only be gradient_rect = QtCore.QRect( 60, # stay to the right of the thumbnail event.rect().bottom() - 8, # only 8 pixels high from the bottom event.rect().right() + 1, # ensure covers full width event.rect().bottom(), ) # vertical gradient gradient = QtGui.QLinearGradient(gradient_rect.topLeft(), gradient_rect.bottomLeft()) # transparent -> base color, in first 15% of height of rect gradient.setColorAt(0, QtGui.QColor(0, 0, 0, 0)) gradient.setColorAt(0.15, self.palette().base().color()) # paint it painter.fillRect(gradient_rect, gradient) painter.end()
def colorize(c1, c1_strength, c2, c2_strength): """Convenience method for making a color from 2 existing colors. :param c1: QtGui.QColor 1 :param c1_strength: int factor of the strength of this color :param c2: QtGui.QColor 2 :param c2_strength: int factor of the strength of this color This is primarily used to prevent hardcoding of colors that don't work in other color palettes. The idea is that you can provide a color from the current widget palette and shift it toward another color. For example, you could get a red-shifted text color by supplying the windowText color for a widget as color 1, and the full red as color 2. Then use the strength args to weight the resulting color more toward the windowText or full red. It's still important to test the resulting colors in multiple color schemes. """ total = c1_strength + c2_strength r = ((c1.red() * c1_strength) + (c2.red() * c2_strength)) / total g = ((c1.green() * c1_strength) + (c2.green() * c2_strength)) / total b = ((c1.blue() * c1_strength) + (c2.blue() * c2_strength)) / total return QtGui.QColor(r, g, b)
def _get_default_thumbnail(self, sg_entity): """ Get the default icon for the specified entity. :param sg_entity: A Shotgun entity dictionary for the entity to get the icon for. :returns: A QIcon for the entity if available. For Step entities, a swatch representing the step colour is returned. If no icon is available for the entity type then the default icon is returned """ if sg_entity.get("type") == "Step": # special case handling for steps to return a colour swatch: step_id = sg_entity.get("id") if step_id != None: # get the colour from the cache: if step_id not in ShotgunEntityModel._SG_STEP_COLOURS: ShotgunEntityModel._SG_STEP_COLOURS[step_id] = None # refresh cache: bundle = sgtk.platform.current_bundle() try: sg_steps = bundle.shotgun.find("Step", [], ["color"]) for sg_step in sg_steps: colour = None try: colour = tuple([ int(c) for c in sg_step.get("color").split(",") ]) except: pass ShotgunEntityModel._SG_STEP_COLOURS[ sg_step["id"]] = colour except: pass colour = ShotgunEntityModel._SG_STEP_COLOURS[step_id] if colour and isinstance(colour, tuple) and len(colour) == 3: # get the icon for this colour from the cache: if colour not in self._step_swatch_icons: # build icon and add to cache: pm = QtGui.QPixmap(16, 16) pm.fill(QtCore.Qt.transparent) painter = QtGui.QPainter(pm) try: painter.setBrush( QtGui.QBrush( QtGui.QColor(colour[0], colour[1], colour[2]))) painter.setPen(QtCore.Qt.black) painter.drawRect(2, 2, 12, 12) finally: painter.end() self._step_swatch_icons[colour] = QtGui.QIcon(pm) # return the icon: return self._step_swatch_icons[colour] # just return the entity icon or the default icon if there is no entity icon: return self.get_entity_icon( sg_entity.get("type")) or self._default_icon
def _ensure_widgets_for_entity_type(self, entity_type): """ Ensure widgets for Steps for the given Entity type are build. :param str entity_type: A Shotgun Entity type. """ widgets = self._step_widgets[entity_type] if widgets: return widgets # Not already built, let's do it now for step in self._step_list[entity_type]: widget = QtGui.QCheckBox(step["code"]) if step["color"]: pixmap = QtGui.QPixmap(100, 100) # Get the Step color and add a bit of transparency to the # color otherwise it is too bright. color = [int(x) for x in step["color"].split(",")] + [200] pixmap.fill(QtGui.QColor(*color)) widget.setIcon(pixmap) # Turn it on if it was in the step saved filters # We do this before the toggled signal is connected to not emit # un-wanted signals. if step["id"] in self._current_filter_step_ids: widget.setChecked(True) widget.toggled.connect(lambda value, step_id=step[ "id"]: self._on_step_filter_toggled(step_id, checked=value)) item = QtGui.QListWidgetItem("", self._list_widget) item.setData(QtCore.Qt.UserRole, step) self._list_widget.setItemWidget(item, widget) self._step_widgets[entity_type].append(widget) return self._step_widgets[entity_type]
def __init__(self, parent=None): """Initialize the widget. :param parent: This widget's parent widget :type parent: :class:`~PySide.QtGui.QWidget` """ super(BubbleWidget, self).__init__(parent) # placeholder for the underlying data this widget represents in the editor self._data = None # should not grow or shrink self.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) # style the look of the bubble self.setObjectName("bubble") self.setStyleSheet(""" #bubble { border: 1px solid black; border-radius: 5px; background-color: %s; } """ % self.palette().color(QtGui.QPalette.Button).name()) # create a remove button for the widget. # extract a close button icon from the style and use it self.remove_button = QtGui.QPushButton(self) style = self.remove_button.style() icon = style.standardIcon(style.SP_TitleBarCloseButton) self.remove_button.setIcon(icon) self.remove_button.setFlat(True) self.remove_button.setStyleSheet("border: none") # placeholder for the bubble's image self.image_label = QtGui.QLabel(self) # color the text to use the SG highlight color text_color = QtGui.QColor(sgtk.platform.current_bundle(). style_constants["SG_HIGHLIGHT_COLOR"]) self.text_label = QtGui.QLabel(self) palette = self.text_label.palette() palette.setColor(QtGui.QPalette.WindowText, text_color) self.text_label.setPalette(palette) # layout the widgets self.layout = QtGui.QHBoxLayout() self.layout.setSizeConstraint(QtGui.QLayout.SetMinimumSize) self.layout.setContentsMargins(3, 1, 3, 1) self.layout.setSpacing(2) self.layout.addWidget(self.image_label, QtCore.Qt.AlignVCenter) self.layout.addWidget(self.text_label, QtCore.Qt.AlignVCenter) self.layout.addWidget(self.remove_button, QtCore.Qt.AlignVCenter) self.setLayout(self.layout) # emit the "remove_clicked" signal when the button is clicked. self.remove_button.clicked.connect(lambda: self.remove_clicked.emit())
def paintEvent(self, event): QtGui.QPushButton.paintEvent(self, event) if self.version: painter = QtGui.QPainter(self) painter.setPen(QtGui.QPen(QtGui.QColor(255, 255, 255, 255))) painter.drawText(self.rect().adjusted(3, 0, 0, 0), QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, str(self.version))
def paintEvent(self, event): """ Paint event """ # Convert click and current mouse positions to local space. mouse_pos = self.mapFromGlobal(QtGui.QCursor.pos()) click_pos = None if self._click_pos is not None: click_pos = self.mapFromGlobal(self._click_pos) painter = QtGui.QPainter(self) # Draw background. Aside from aesthetics, this makes the full # tool region accept mouse events. painter.setBrush(QtGui.QColor(0, 0, 0, self._opacity)) painter.setPen(QtCore.Qt.NoPen) painter.drawRect(event.rect()) # Clear the capture area if click_pos is not None: capture_rect = QtCore.QRect(click_pos, mouse_pos) painter.setCompositionMode(QtGui.QPainter.CompositionMode_Clear) painter.drawRect(capture_rect) painter.setCompositionMode(QtGui.QPainter.CompositionMode_SourceOver) pen = QtGui.QPen(QtGui.QColor(255, 255, 255, 64), 1, QtCore.Qt.DotLine) painter.setPen(pen) # Draw cropping markers at click position if click_pos is not None: painter.drawLine( event.rect().left(), click_pos.y(), event.rect().right(), click_pos.y() ) painter.drawLine( click_pos.x(), event.rect().top(), click_pos.x(), event.rect().bottom() ) # Draw cropping markers at current mouse position painter.drawLine( event.rect().left(), mouse_pos.y(), event.rect().right(), mouse_pos.y() ) painter.drawLine( mouse_pos.x(), event.rect().top(), mouse_pos.x(), event.rect().bottom() )
def clear_highlight(self): original_format = QtGui.QTextCharFormat() original_format.setBackground( QtGui.QBrush(QtGui.QColor(0, 0, 0), QtCore.Qt.NoBrush) ) cursor = self.__logs.textCursor() cursor.select(QtGui.QTextCursor.Document) cursor.mergeCharFormat(original_format) cursor.clearSelection() self.__logs.setTextCursor(cursor)
def _error_text_color(self): """The error text color.""" if not hasattr(self, '_err_color'): self._err_color = colorize( self.textColor(), 1, QtGui.QColor(255, 0, 0), 3, ) return self._err_color
def _input_text_color(self): """The input text color.""" if not hasattr(self, '_input_color'): self._input_color = colorize( self.palette().base().color(), 1, QtGui.QColor(127, 127, 127), 2, ) return self._input_color
def test_create_snapshot(self): """ Tests getting the current work path and saving a snapshot, using the snapshot app's API. """ # This tests both the saving an getting of the current work path operations in the scene operations hook. self._create_file("ufo") from sgtk.platform.qt import QtGui thumbnail = QtGui.QPixmap(100, 100) thumbnail.fill(QtGui.QColor("red")) # This will trigger the scene operations hook to be called twice, for a current_path, and save operation. snapshot_path = self.app.snapshot("my comment", thumbnail) self.assertTrue(os.path.exists(snapshot_path))
def __format_thumbnail(self, pixmap_obj): """ Given a screengrab, create a thumbnail object, scaled to 96x75 px and with a subtle rounded frame. :param pixmap_obj: input screenshot :returns: 96x75px pixmap """ CANVAS_WIDTH = 96 CANVAS_HEIGHT = 75 CORNER_RADIUS = 6 # get the 512 base image base_image = QtGui.QPixmap(CANVAS_WIDTH, CANVAS_HEIGHT) base_image.fill(QtCore.Qt.transparent) # scale it down to fit inside a frame of maximum 512x512 thumb_scaled = pixmap_obj.scaled(CANVAS_WIDTH, CANVAS_HEIGHT, QtCore.Qt.KeepAspectRatioByExpanding, QtCore.Qt.SmoothTransformation) # now composite the thumbnail on top of the base image # bottom align it to make it look nice thumb_img = thumb_scaled.toImage() brush = QtGui.QBrush(thumb_img) painter = QtGui.QPainter(base_image) painter.setRenderHint(QtGui.QPainter.Antialiasing) painter.setBrush(brush) pen = QtGui.QPen(QtGui.QColor("#2C93E2")) pen.setWidth(3) painter.setPen(pen) # note how we have to compensate for the corner radius painter.drawRoundedRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, CORNER_RADIUS, CORNER_RADIUS) painter.end() return base_image
def paintEvent(self, event): """ Render the UI. """ if self._mode == self.MODE_OFF: return painter = QtGui.QPainter() painter.begin(self) try: # set up semi transparent backdrop painter.setRenderHint(QtGui.QPainter.Antialiasing) overlay_color = QtGui.QColor(30, 30, 30, 160) painter.setBrush( QtGui.QBrush(overlay_color)) painter.setPen(QtGui.QPen(overlay_color)) painter.drawRect(0, 0, painter.device().width(), painter.device().height()) finally: painter.end()
def paintEvent(self, paint_event): """ Paints the line plain text editor and adds a placeholder on bottom right corner when multiple values are detected. """ # If the box does not have focus, draw <multiple values> placeholder when self._show_placeholder is true, even if the widget has text if not self.hasFocus() and self._show_placeholder == True: p = QtGui.QPainter(self.viewport()) # right placeholder note in blue col = QtGui.QColor(24,167,227) # blue p.setPen(QtGui.QPen(col)) p.setBrush(QtGui.QBrush(col)) p.drawText(self.rect(),QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft, self._placeholder_text) else: QtGui.QPlainTextEdit.paintEvent(self, paint_event)
def drawBranches(self, painter, rect, index): """ Overrides drawing of the branches - The bit that sits to the left of the item and usually contains the native expand collapse button. This feels a bit hacky, but since we are providing our own button, and we don't want to show the native branches area, we are shifting the items along to sit over the top of it in the style.qss (see #items_tree::item). However the selection box does not shift, so we are overriding this method to paint in the remainder of the selection box covering the branch area. """ # First draw the default visuals for the branch. super(PublishTreeWidget, self).drawBranches(painter, rect, index) if index in self.selectedIndexes(): # Draw the selection boarder around the shifted item. # The provided QRec instance will cover everything from the far left to the beginning of the item # but since we only to draw the selection box around the item in the branch area, we should shift the # start point in in line with the item shift in the style sheet. rect.setX(rect.x() + rect.width() - 28) color = QtGui.QColor(self._bundle.style_constants["SG_HIGHLIGHT_COLOR"]) painter.fillRect(rect, color)
def paintEvent(self, paint_event): """ Paints the line plain text editor and adds a placeholder on bottom right corner when multiple values are detected. """ # If the box does not have focus, draw <multiple values> placeholder when self._show_placeholder is true, even if the widget has text if not self.hasFocus() and self._show_multiple_values is True: p = QtGui.QPainter(self.viewport()) # right placeholder note in blue col = QtGui.QColor(self._highlight) # blue p.setPen(QtGui.QPen(col)) p.setBrush(QtGui.QBrush(col)) p.drawText( self.rect(), QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft, self._multiple_values_text, ) else: super(PublishDescriptionEditBase, self).paintEvent(paint_event)
def createOverlayPixmap(self, alpha=45): px = float(self.attachmentPixmap.width()) / 3.0 py = float(self.attachmentPixmap.height()) / 3.0 pf = px if px > py: pf = py overPix = QtGui.QPixmap(self.overImagePath).scaled( pf, pf, QtCore.Qt.KeepAspectRatio) self.resultPix = QtGui.QPixmap(self.attachmentPixmap.width(), self.attachmentPixmap.height()) self.resultPix.fill(QtCore.Qt.transparent) painter = QtGui.QPainter(self.resultPix) painter.drawPixmap(0, 0, self.attachmentPixmap) painter.fillRect(0, 0, self.attachmentPixmap.width(), self.attachmentPixmap.height(), QtGui.QColor(0, 0, 0, alpha)) painter.drawPixmap(px, py, overPix) del painter
def find_all(self, pattern, logs): highlight_format = QtGui.QTextCharFormat() highlight_format.setBackground( QtGui.QBrush(QtGui.QColor(80, 80, 80)) ) regex = QtCore.QRegExp(pattern, QtCore.Qt.CaseInsensitive) matches = [] pos = 0 index = regex.indexIn(logs, pos) count = 0 while (index != -1): count += 1 matched_length = regex.matchedLength() # append start index and length of last matched string # length could be different matches.append((index, matched_length)) # select the matched text and apply the desired format self.highlight_one(index, matched_length, highlight_format) # Move to the next match pos = index + matched_length index = regex.indexIn(logs, pos) return matches
def _style(self, style_type): palette = self._palette styles = { 'keyword': _format( colorize( palette.windowText().color(), 3, QtGui.QColor(0, 0, 255), 1, ), style="", ), 'builtin': _format( colorize( palette.windowText().color(), 3, QtGui.QColor(0, 255, 0), 1, ), style="", ), 'operator': _format( colorize( palette.windowText().color(), 4, palette.highlight().color(), 2, ), style="", ), 'brace': _format( colorize( palette.windowText().color(), 2, palette.base().color(), 1, ), style="bold", ), 'defclass': _format( colorize( palette.windowText().color(), 3, QtGui.QColor(255, 0, 0), 1, ), style="bold", ), 'string': _format( colorize( palette.windowText().color(), 2, palette.highlight().color(), 1, ), style="bold", ), 'string2': _format( colorize( palette.windowText().color(), 1, palette.base().color(), 1, ), style="", ), 'comment': _format( colorize( palette.windowText().color(), 1, palette.base().color(), 2, ), style="italic", ), 'self': _format( colorize( palette.windowText().color(), 1, QtGui.QColor(127, 127, 127), 1, ), style="", ), 'numbers': _format( colorize( palette.windowText().color(), 3, QtGui.QColor(127, 127, 127), 1, ), style="", ), } return styles[style_type]
def _set_row_color(self, row, color_name): if color_name == 'bright green': row_color = QtGui.QColor(240, 255, 220) elif color_name == 'green': row_color = QtGui.QColor(200, 255, 200) elif color_name == 'blue': row_color = QtGui.QColor(140, 150, 220) elif color_name == 'light blue': row_color = QtGui.QColor(240, 240, 255) elif color_name == 'red': row_color = QtGui.QColor(255, 96, 96) elif color_name == 'dark red': row_color = QtGui.QColor(180, 16, 16) elif color_name == 'violet': row_color = QtGui.QColor(240, 230, 255) elif color_name == 'ultra_violet': row_color = QtGui.QColor(230, 210, 255) elif color_name == 'yellow': row_color = QtGui.QColor(128, 128, 48) elif color_name == 'gray': row_color = QtGui.QColor(96, 96, 96) elif color_name == 'default': if self.default_color: row_color = self.default_color else: row_color = QtGui.QColor(96, 96, 96) else: # no match row_color = QtGui.QColor(255, 255, 255) for col in range(self.table.columnCount()): item = self.table.item(row, col) if item: item.setBackground(row_color)
def _create_table(self): # set initial rows and columns row_count = len(self.edl_data) + 1 column_count = len(self.header_list) self.ui.table.setRowCount(row_count) self.ui.table.setColumnCount(column_count) black = QtGui.QColor(0, 0, 0) logger.info('Creating table header row') # create table header row col_num = 0 for header_name in self.header_list: item = QtGui.QTableWidgetItem() item.setText(header_name) item.setBackground(black) item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) # not ItemIsEditable self.ui.table.setItem(0, col_num, item) col_num += 1 logger.info('Adding EDL data to table') # add all rows of edl data to the table for row_num, shot_dict in enumerate(self.edl_data): row_num += 1 # adjust for header row col_num = 0 # use header names as keys for k in self.header_list: item = QtGui.QTableWidgetItem() if k == 'Import': checkbox = QtGui.QCheckBox() checkbox.setCheckState(QtCore.Qt.Checked) self.ui.table.setCellWidget(row_num, col_num, checkbox) else: item = QtGui.QTableWidgetItem() if k == 'Entity Type': item.setText('Element') else: item.setText(shot_dict[k]) item.setFlags( QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) # not ItemIsEditable self.ui.table.setItem(row_num, col_num, item) col_num += 1 # create list of parents shots in table parent_shot_list = list() parent_shots_column = self.header_list.index('Parent Shots') for row in range(1, self.ui.table.rowCount() + 1): item = self.ui.table.item(row, parent_shots_column) if item and item.text(): parent_shot = item.text() if parent_shot not in parent_shot_list: parent_shot_list.append(parent_shot) # TODO: REMOVE THIS logger.info('Checking shotgun for existing parent shots') # check shotgun for parent shots that may have been previously created # make a list of any shots that need to be created create_new_shot_list = list() for parent_shot in parent_shot_list: # find in shotgun shot = self.sg.find_one( 'Shot', [['project', 'is', self.project], ['code', 'is', parent_shot]]) if not shot and parent_shot not in create_new_shot_list: create_new_shot_list.append(parent_shot) logger.info('Adding parent shots to table') # add new shots to table for shot_name in create_new_shot_list: row = 0 col = self.header_list.index('Parent Shots') # find the shot in the table, we need the row number for row in range(1, self.ui.table.rowCount() + 1): item = self.ui.table.item(row, col) if item.text() == shot_name: break if row == 0: continue episode_item = self.ui.table.item( row, self.header_list.index('Episode')) sequence_item = self.ui.table.item( row, self.header_list.index('Sequence')) episode = '' sequence = '' if episode_item: episode = episode_item.text() if sequence_item: sequence = sequence_item.text() # find where to insert new shot row # loop through rows until an "Element" is found # we will insert new shot row before the element row new_row_number = 1 for new_row_number in range(1, self.ui.table.rowCount()): item = self.ui.table.item( new_row_number, self.header_list.index('Entity Type')) if item.text() == 'Element': break self.ui.table.insertRow(new_row_number) # add new shot to table for header_name in self.header_list: item = QtGui.QTableWidgetItem() if header_name == 'Episode': item.setText(episode) elif header_name == 'Sequence': item.setText(sequence) elif header_name == 'Shot Code': item.setText(shot_name) elif header_name == 'Entity Type': item.setText('Shot') self.ui.table.setItem(new_row_number, self.header_list.index(header_name), item) checkbox = QtGui.QCheckBox() checkbox.setCheckState(QtCore.Qt.Checked) self.ui.table.setCellWidget(new_row_number, self.ui.table.columnCount() - 1, checkbox) # remove all flags to disable item # item.setFlags(QtCore.Qt.NoItemFlags) # set a flag # note this will wipe out other flag values # item.setFlags(QtCore.Qt.ItemIsSelectable) # set several flags # item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable) self.setMinimumSize(1500, 540) self.resize(1500, 540) self.ui.button_file_open.hide() self.ui.button_shotgun_import.show() self.update()
def _set_row_color(self, row, color_name): """Set row color based on name :param row: int :param color_name: str :return: None """ if color_name == 'bright green': row_color = QtGui.QColor(240, 255, 220) elif color_name == 'green': row_color = QtGui.QColor(200, 255, 200) elif color_name == 'blue': row_color = QtGui.QColor(140, 150, 220) elif color_name == 'light blue': row_color = QtGui.QColor(240, 240, 255) elif color_name == 'red': row_color = QtGui.QColor(200, 0, 0) elif color_name == 'dark red': row_color = QtGui.QColor(128, 0, 0) elif color_name == 'violet': row_color = QtGui.QColor(240, 230, 255) elif color_name == 'ultra_violet': row_color = QtGui.QColor(230, 210, 255) elif color_name == 'gray': row_color = QtGui.QColor(200, 200, 200) elif color_name == 'dark gray': row_color = QtGui.QColor(48, 48, 48) elif color_name == 'yellow': row_color = QtGui.QColor(112, 112, 0) else: # default row_color = QtGui.QColor(128, 128, 128) for col in range(self.ui.table.columnCount()): item = self.ui.table.item(row, col) if item: item.setBackground(row_color)
def paint(self, painter, style_options, model_index): """ Paint method to handle all cells that are not being currently edited. :param painter: The painter instance to use when painting :param style_options: The style options to use when painting :param model_index: The index in the data model that needs to be painted """ sg_item = shotgun_model.get_sg_data(model_index) original_tn = model_index.data(self._ORIGINAL_THUMBNAIL) pinned_tn = model_index.data(self._PINNED_THUMBNAIL) filter_tn = model_index.data(self._FILTER_THUMBNAIL) # for performance reasons, we are not creating a widget every time # but merely moving the same widget around. paint_widget = self._get_painter_widget(model_index, self.parent()) if not paint_widget: # just paint using the base implementation: QtGui.QStyledItemDelegate.paint(self, painter, style_options, model_index) return # make sure that the widget that is just used for painting isn't visible otherwise # it'll appear in the wrong place! paint_widget.setVisible(False) # call out to have the widget set the right values self._on_before_paint(paint_widget, model_index, style_options) # now paint! painter.save() try: paint_widget.resize(style_options.rect.size()) painter.translate(style_options.rect.topLeft()) # note that we set the render flags NOT to render the background of the widget # this makes it consistent with the way the editor widget is mounted inside # each element upon hover. paint_widget.render(painter, QtCore.QPoint(0, 0), renderFlags=QtGui.QWidget.DrawChildren) if self.tray_view.rv_mode.index_is_pinned(model_index.row()): painter.drawPixmap( paint_widget.width() - self.pin_pixmap.width(), 0, self.pin_pixmap) if not sg_item.get('version.Version.id') and not sg_item.get( 'image') and not sg_item.get( 'cut.Cut.version.Version.image'): target = QtCore.QRectF(0.0, 0.0, paint_widget.width(), paint_widget.height()) source = QtCore.QRectF(0, 0, self.missing_pixmap.width(), self.missing_pixmap.height()) # painter.drawPixmap(target, self.missing_pixmap, source) painter.fillRect(0, 0, paint_widget.width(), paint_widget.height(), QtGui.QColor(10, 0, 0, 255)) painter.drawText( 0, 5, 100, 100, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignCenter, 'MISSING') mini_data = self.tray_view.rv_mode.cached_mini_cut_data if mini_data.active and painter: if mini_data.focus_clip == model_index.row(): painter.setPen(self._pen) ws = paint_widget.size() painter.drawRect(1, 1, ws.width() - 2, ws.height() - 2) if mini_data.first_clip > model_index.row( ) or mini_data.last_clip < model_index.row(): painter.fillRect(0, 0, paint_widget.width(), paint_widget.height(), QtGui.QColor(0, 0, 0, 220)) finally: painter.restore()
def pre_app_init(self): """ Runs before apps have been initialized. """ # Get Qt module regardless of version from sgtk.platform.qt import QtGui, QtCore # Here we're going to set the hyperlink text color to white # since the default is a dark blue that is pretty much unreadable # in a dark color environment like RV. It would be great if we # could style this in qss and only affect toolkit apps, but that's # no possible. As a result, we're modifying the QApplication-level # palette, which is also going to affect RV itself. This is generally # a BAD IDEA, but in this one case it is the best compromise solution # available. palette = QtGui.QApplication.palette() link_color = QtGui.QColor(255, 255, 255) palette.setColor(QtGui.QPalette.Link, link_color) palette.setColor(QtGui.QPalette.LinkVisited, link_color) palette.setColor(QtGui.QPalette.Button, QtGui.QColor(37, 38, 41)) QtGui.QApplication.setPalette(palette) # We can't use import_framework here because the engine.py # wasn't imported via import_module itself. As a result, we # forgo the convenience and grab the framework ourselves and # import the submodules we need directly. shotgun_utils = self.frameworks["tk-framework-shotgunutils"] shotgun_globals = shotgun_utils.import_module("shotgun_globals") task_manager = shotgun_utils.import_module("task_manager") # We need a QObject to act as a parent for the task manager. # This will keep them and their threads from being garbage # collected prematurely by Qt. self.__task_parent = QtCore.QObject() # We will provide a task manager that apps can share. self._bg_task_manager = task_manager.BackgroundTaskManager( parent=self.__task_parent, start_processing=True, max_threads=RVEngine.MAX_THREADS, ) shotgun_globals.register_bg_task_manager(self._bg_task_manager) # The "qss_watcher" setting causes us to monitor the engine's # style.qss file and re-apply it on the fly when it changes # on disk. This is very useful for development work, if self.get_setting("qss_watcher", False): self._qss_watcher = QtCore.QFileSystemWatcher([ os.path.join(self.disk_location, constants.BUNDLE_STYLESHEET_FILE) ], ) self._qss_watcher.fileChanged.connect(self.reload_qss) # The assumption here is that the default case has us presenting a # Shotgun menu and loading it with at least Cutz Support and maybe # an expected Shotgun browser or two. _ui_enabled turns the menu on. # For shell access, setenv TK_RV_NO_UI NCC-1701 this is basically what # tk-maya does so following along. self._ui_enabled = os.environ.get("TK_RV_NO_UI") or True # Unicode characters returned by the shotgun api need to be converted # to display correctly in all of the app windows. Tell Qt to interpret # C strings as utf-8. utf8 = QtCore.QTextCodec.codecForName("utf-8") QtCore.QTextCodec.setCodecForCStrings(utf8)