def __init__(self, parent=None): """ Initialize the widget. """ # call the base class init super(HelpDemo, self).__init__(parent) # --- add some helper labels with arrows and text... summary_lbl = QtGui.QLabel() summary_lbl.setPixmap(QtGui.QPixmap(":/tk_multi_demo_help/summary_help.png")) select_lbl = QtGui.QLabel() select_lbl.setPixmap(QtGui.QPixmap(":/tk_multi_demo_help/select_help.png")) tabs_lbl = QtGui.QLabel() tabs_lbl.setPixmap(QtGui.QPixmap(":/tk_multi_demo_help/tabs_help.png")) # lay out the widgets in the UI layout = QtGui.QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(summary_lbl) layout.addStretch() layout.addWidget(select_lbl) layout.addStretch() layout.addWidget(tabs_lbl) # align the appropriately layout.setAlignment(summary_lbl, QtCore.Qt.AlignCenter | QtCore.Qt.AlignTop) layout.setAlignment(select_lbl, QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) layout.setAlignment(tabs_lbl, QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom)
def _load_plugin_icon(self): """ Loads the icon defined by the hook. :returns: QPixmap or None if not found """ # TODO: this needs to be refactored. should be no UI stuff here from sgtk.platform.qt import QtGui # load plugin icon pixmap = None try: icon_path = self._hook_instance.icon if icon_path: try: pixmap = QtGui.QPixmap(icon_path) except Exception, e: self._logger.warning("%r: Could not load icon '%s': %s" % (self, icon_path, e)) except AttributeError: # plugin does not have an icon pass # load default pixmap if hook doesn't define one if pixmap is None: pixmap = QtGui.QPixmap(":/tk_multi_publish2/task.png") return pixmap
def __init__(self, parent): """ :param parent: The model parent. :type parent: :class:`~PySide.QtGui.QObject` """ super(WorkAreaButton, self).__init__(parent) # an icon to represent all items which # aren't the current work area self._normal_icon = QtGui.QIcon() self._normal_icon.addPixmap( QtGui.QPixmap(":/tk_multi_infopanel/pin.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) # an icon to represent the current work area self._current_work_area_icon = QtGui.QIcon() self._current_work_area_icon.addPixmap( QtGui.QPixmap(":/tk_multi_infopanel/pin_blue.png"), QtGui.QIcon.Disabled, QtGui.QIcon.Off) self.setIcon(self._normal_icon) self.setIconSize( QtCore.QSize(self.WIDGET_WIDTH_COLLAPSED, self.WIDGET_HEIGHT)) self._bundle = sgtk.platform.current_bundle() self._entity_type = None self._entity_id = None self._is_static = False self._caption = "Set Work Area" self._width = 120 self.clicked.connect(self._on_click) self.setVisible(False)
def _populate_thumbnail(self, item, field, path): """ Called whenever a thumbnail for an item has arrived on disk. In the case of an already cached thumbnail, this may be called very soon after data has been loaded, in cases when the thumbs are downloaded from Shotgun, it may happen later. This method will be called only if the model has been instantiated with the download_thumbs flag set to be true. It will be called for items which are associated with shotgun entities (in a tree data layout, this is typically leaf nodes). This method makes it possible to control how the thumbnail is applied and associated with the item. The default implementation will simply set the thumbnail to be icon of the item, but this can be altered by subclassing this method. Any thumbnails requested via the _request_thumbnail_download() method will also resurface via this callback method. :param item: QStandardItem which is associated with the given thumbnail :param field: The Shotgun field which the thumbnail is associated with. :param path: A path on disk to the thumbnail. This is a file in jpeg format. """ if field == "image": thumb = QtGui.QPixmap(path) item.setData(thumb, SgPublishHistoryModel.PUBLISH_THUMB_ROLE) else: thumb = QtGui.QPixmap(path) item.setData(thumb, SgPublishHistoryModel.USER_THUMB_ROLE) # composite the user thumbnail and the publish thumb into a single image thumb = utils.create_overlayed_user_publish_thumbnail( item.data(SgPublishHistoryModel.PUBLISH_THUMB_ROLE), item.data(SgPublishHistoryModel.USER_THUMB_ROLE)) item.setIcon(QtGui.QIcon(thumb))
def __init__(self): # loading a pixmap self.loading = create_rectangular_thumbnail( QtGui.QPixmap( ":/tk_framework_qtwidgets.global_search_widget/loading.png" ) ) # more typing required self.keyboard = create_rectangular_thumbnail( QtGui.QPixmap( ":/tk_framework_qtwidgets.global_search_widget/keyboard.png" ) ) # no matches found self.no_matches = create_rectangular_thumbnail( QtGui.QPixmap( ":/tk_framework_qtwidgets.global_search_widget/no_match.png" ) ) # no thumbnail for the entity self.no_thumbnail = create_rectangular_thumbnail( QtGui.QPixmap( ":/tk_framework_qtwidgets.global_search_widget/no_thumbnail.png" ) )
def _load_plugin_icon(self): """ Loads the icon defined by the hook. :returns: QPixmap or None if not found """ # load plugin icon pixmap = None try: icon_path = self._hook_instance.icon try: pixmap = QtGui.QPixmap(icon_path) except Exception, e: self._logger.warning( "%r: Could not load icon '%s': %s" % (self, icon_path, e) ) except AttributeError: # plugin does not have an icon pass # load default pixmap if hook doesn't define one if pixmap is None: pixmap = QtGui.QPixmap(":/tk_multi_publish2/item.png") return pixmap
def _load_plugin_icon(self): """ Loads the icon defined by the plugin's hook. :returns: QPixmap or None if not found """ # defer import until needed and to avoid issues when running without UI from sgtk.platform.qt import QtGui # load plugin icon pixmap = None try: icon_path = self._hook_instance.icon if icon_path: try: pixmap = QtGui.QPixmap(icon_path) except Exception as e: self._logger.warning("%r: Could not load icon '%s': %s" % (self, icon_path, e)) except AttributeError: # plugin does not have an icon pass # load default pixmap if hook doesn't define one if pixmap is None: pixmap = QtGui.QPixmap(":/tk_multi_publish2/task.png") return pixmap
def __init__(self, parent): """ Construction """ QtGui.QWidget.__init__(self, parent) # set up the UI self._ui = Ui_FileWidget() self._ui.setupUi(self) # store the app to use when calling hooks self._app = sgtk.platform.current_bundle() # create the status icons and add them to a layout over the main thumbnail: self._publish_icon = QtGui.QLabel(self) self._publish_icon.setMinimumSize(16, 16) self._publish_icon.setAlignment(QtCore.Qt.AlignCenter) self._publish_icon.setPixmap( QtGui.QPixmap(":/tk-multi-workfiles2/publish_icon.png")) self._publish_icon.hide() # not sure I like this - think I preferred it when it was over on the right of the tile! self._lock_icon = QtGui.QLabel(self) self._lock_icon.setMinimumSize(16, 16) self._lock_icon.setAlignment(QtCore.Qt.AlignCenter) self._lock_icon.setPixmap( QtGui.QPixmap(":/tk-multi-workfiles2/padlock.png")) self._lock_icon.hide() rhs_layout = QtGui.QVBoxLayout() rhs_layout.setContentsMargins(0, 0, 0, 0) rhs_layout.setSpacing(0) rhs_layout.addWidget(self._lock_icon) rhs_layout.addStretch(1) rhs_layout.addWidget(self._publish_icon) # A hook-defined badge (upper left) self._badge_icon = QtGui.QLabel(self) self._badge_icon.setMinimumSize(16, 16) self._badge_icon.setAlignment(QtCore.Qt.AlignCenter) self._badge_icon.hide() lhs_layout = QtGui.QVBoxLayout() lhs_layout.setContentsMargins(0, 0, 0, 0) lhs_layout.setSpacing(0) lhs_layout.addStretch(1) lhs_layout.addWidget(self._badge_icon) thumb_layout = QtGui.QHBoxLayout(self._ui.thumbnail) thumb_layout.setContentsMargins(4, 4, 4, 4) thumb_layout.setSpacing(0) thumb_layout.addLayout(lhs_layout) thumb_layout.addStretch() thumb_layout.addLayout(rhs_layout) self._ui.thumbnail.setLayout(thumb_layout) self._is_selected = False self._update_ui()
def __init__(self, entity_type): """ Constructor """ self._entity_type = entity_type self._round_default_icon = QtGui.QPixmap( ":/tk_multi_infopanel/round_512x400.png") self._rect_default_icon = QtGui.QPixmap( ":/tk_multi_infopanel/rect_512x400.png") self._app = sgtk.platform.current_bundle() # read in the hook data into a dict self._hook_data = {} self._hook_data[ "get_list_item_definition"] = self._app.execute_hook_method( "shotgun_fields_hook", "get_list_item_definition", entity_type=entity_type) self._hook_data["get_all_fields"] = self._app.execute_hook_method( "shotgun_fields_hook", "get_all_fields", entity_type=entity_type) self._hook_data[ "get_main_view_definition"] = self._app.execute_hook_method( "shotgun_fields_hook", "get_main_view_definition", entity_type=entity_type) # extract a list of fields given all the different {tokens} defined fields = [] fields += self._resolve_sg_fields( self._get_hook_value("get_list_item_definition", "top_left")) fields += self._resolve_sg_fields( self._get_hook_value("get_list_item_definition", "top_right")) fields += self._resolve_sg_fields( self._get_hook_value("get_list_item_definition", "body")) fields += self._resolve_sg_fields( self._get_hook_value("get_main_view_definition", "title")) fields += self._resolve_sg_fields( self._get_hook_value("get_main_view_definition", "body")) # also include the thumbnail field so that it gets retrieved as part of the general # query payload fields.extend(self.thumbnail_fields) # include the special quicktime field for versions if entity_type == "Version": fields.append("sg_uploaded_movie") fields.append("sg_path_to_frames") if entity_type == "Note": fields.append("read_by_current_user") fields.append("client_note") if entity_type == "PublishedFile": fields.append("path") self._token_fields = set(fields)
def setupUi(self, Dialog): Dialog.setObjectName("Dialog") Dialog.resize(490, 618) self.verticalLayout = QtGui.QVBoxLayout(Dialog) self.verticalLayout.setObjectName("verticalLayout") self.browser = SceneBrowserWidget(Dialog) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.browser.sizePolicy().hasHeightForWidth()) self.browser.setSizePolicy(sizePolicy) self.browser.setObjectName("browser") self.verticalLayout.addWidget(self.browser) self.horizontalLayout_3 = QtGui.QHBoxLayout() self.horizontalLayout_3.setSpacing(3) self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.groupBox = QtGui.QGroupBox(Dialog) self.groupBox.setTitle("") self.groupBox.setObjectName("groupBox") self.horizontalLayout_2 = QtGui.QHBoxLayout(self.groupBox) self.horizontalLayout_2.setSpacing(10) self.horizontalLayout_2.setContentsMargins(2, 2, 2, 2) self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.label = QtGui.QLabel(self.groupBox) self.label.setObjectName("label") self.horizontalLayout_2.addWidget(self.label) self.chk_green = QtGui.QCheckBox(self.groupBox) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(":/res/green_bullet.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.chk_green.setIcon(icon) self.chk_green.setObjectName("chk_green") self.horizontalLayout_2.addWidget(self.chk_green) self.chk_red = QtGui.QCheckBox(self.groupBox) icon1 = QtGui.QIcon() icon1.addPixmap(QtGui.QPixmap(":/res/red_bullet.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.chk_red.setIcon(icon1) self.chk_red.setObjectName("chk_red") self.horizontalLayout_2.addWidget(self.chk_red) self.horizontalLayout_3.addWidget(self.groupBox) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem) self.select_all = QtGui.QPushButton(Dialog) self.select_all.setObjectName("select_all") self.horizontalLayout_3.addWidget(self.select_all) self.update = QtGui.QPushButton(Dialog) self.update.setObjectName("update") self.horizontalLayout_3.addWidget(self.update) self.verticalLayout.addLayout(self.horizontalLayout_3) self.retranslateUi(Dialog) QtCore.QMetaObject.connectSlotsByName(Dialog)
def create_rectangular_thumbnail(thumb): """ Scale a given pixmap down to a given resolution :param thumb: pixmap to scale :returns: scaled thumbnail """ # TODO: this would be great to add to the qtwidgets framework CANVAS_WIDTH = 48 CANVAS_HEIGHT = 38 if thumb.isNull(): # to be safe, if thumb is null, use the empty/default thumbnail thumb = QtGui.QPixmap( ":/tk_framework_qtwidgets.global_search_widget/no_thumbnail.png" ) # 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 512x400 thumb_scaled = thumb.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) # figure out the offset height wise in order to center the thumb height_difference = CANVAS_HEIGHT - thumb_scaled.height() width_difference = CANVAS_WIDTH - thumb_scaled.width() # center it with wise inlay_offset_w = width_difference / 2 # bottom height wise # inlay_offset_h = height_difference+CORNER_RADIUS inlay_offset_h = height_difference / 2 # note how we have to compensate for the corner radius painter.translate(inlay_offset_w, inlay_offset_h) painter.drawRect(0, 0, thumb_scaled.width(), thumb_scaled.height()) painter.end() return base_image
def __init__(self, app, worker, parent=None): """ Construction """ browser_widget.ListItem.__init__(self, app, worker, parent) self._green_pixmap = QtGui.QPixmap(":/res/green_bullet.png") self._red_pixmap = QtGui.QPixmap(":/res/red_bullet.png") self._latest_version = None self._is_latest = None
def create_overlayed_publish_thumbnail(path): """ Given a path to a shotgun thumbnail, create a publish icon with the thumbnail composited onto a centered otherwise empty canvas. This will return a 512x400 pixmap object. """ CANVAS_WIDTH = 512 CANVAS_HEIGHT = 400 CORNER_RADIUS = 10 # get the 512 base image base_image = QtGui.QPixmap(CANVAS_WIDTH, CANVAS_HEIGHT) base_image.fill(QtCore.Qt.transparent) # now attempt to load the image # pixmap will be a null pixmap if load fails thumb = QtGui.QPixmap(path) if not thumb.isNull(): # scale it down to fit inside a frame of maximum 512x512 thumb_scaled = thumb.scaled(CANVAS_WIDTH, CANVAS_HEIGHT, QtCore.Qt.KeepAspectRatio, 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) # figure out the offset height wise in order to center the thumb height_difference = CANVAS_HEIGHT - thumb_scaled.height() width_difference = CANVAS_WIDTH - thumb_scaled.width() # center it with wise inlay_offset_w = (width_difference / 2) + (CORNER_RADIUS / 2) # bottom height wise #inlay_offset_h = height_difference+CORNER_RADIUS inlay_offset_h = (height_difference / 2) + (CORNER_RADIUS / 2) # note how we have to compensate for the corner radius painter.translate(inlay_offset_w, inlay_offset_h) painter.drawRoundedRect(0, 0, thumb_scaled.width() - CORNER_RADIUS, thumb_scaled.height() - CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS) painter.end() return base_image
def __init__(self, parent): """ Constructor :param parent: QT parent object """ QtGui.QLabel.__init__(self, parent) self._play_icon = QtGui.QPixmap(":/tk_multi_infopanel_version_label/play_icon.png") self._play_icon_inactive = QtGui.QPixmap(":/tk_multi_infopanel_version_label/play_icon_inactive.png") self._sg_data = None self._hover = False self._active = False
def __init__(self, parent): """ :param parent: The parent QWidget for this control :type parent: :class:`~PySide.QtGui.QWidget` """ # first, call the base class and let it do its thing. QtGui.QWidget.__init__(self, parent) # now load in the UI that was created in the UI designer self.ui = Ui_NoteInputWidget() self.ui.setupUi(self) self._load_stylesheet() # set up some handy references self._bundle = sgtk.platform.current_bundle() self._camera_icon = QtGui.QIcon( QtGui.QPixmap( ":/tk_framework_qtwidgets.note_input_widget/camera_hl.png")) self._trash_icon = QtGui.QIcon( QtGui.QPixmap( ":/tk_framework_qtwidgets.note_input_widget/trash.png")) # initialize state variables self._processing_id = None # async task id self._entity_type = None # current associated entity self._entity_id = None # current associated entity self._pixmap = None # self._attachments = [] self._cleanup_after_upload = [] # set up an overlay that spins when note is submitted self.__overlay = SmallOverlayWidget(self) # create a separate sg data handler for submission self.__sg_data_retriever = None # hook up signals and slots self.ui.screenshot.clicked.connect(self._screenshot_or_clear) self.ui.submit.clicked.connect(self._submit) self.ui.close.clicked.connect(self._cancel) self.ui.close.clicked.connect(self.close_clicked) self.ui.attach.clicked.connect(self.open_attachments) self.ui.add_attachments.clicked.connect(self._apply_attachments) self.ui.close_attachments.clicked.connect(self._cancel_attachments) self.ui.add_button.clicked.connect(self._add_attachments) self.ui.remove_button.clicked.connect( self._remove_selected_attachments) # reset state of the UI self.pre_submit_callback = None self.clear()
def setupUi(self, Item): Item.setObjectName("Item") Item.resize(329, 65) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(Item.sizePolicy().hasHeightForWidth()) Item.setSizePolicy(sizePolicy) Item.setMinimumSize(QtCore.QSize(0, 65)) self.verticalLayout = QtGui.QVBoxLayout(Item) self.verticalLayout.setSpacing(2) self.verticalLayout.setContentsMargins(2, 2, 2, 2) self.verticalLayout.setObjectName("verticalLayout") self.background = ClickBubblingGroupBox(Item) self.background.setTitle("") self.background.setObjectName("background") self.horizontalLayout = QtGui.QHBoxLayout(self.background) self.horizontalLayout.setSpacing(8) self.horizontalLayout.setContentsMargins(10, 2, 2, 2) self.horizontalLayout.setObjectName("horizontalLayout") self.light = QtGui.QLabel(self.background) self.light.setText("") self.light.setPixmap(QtGui.QPixmap(":/res/empty_bullet.png")) self.light.setObjectName("light") self.horizontalLayout.addWidget(self.light) self.thumbnail = ThumbnailLabel(self.background) self.thumbnail.setMinimumSize(QtCore.QSize(60, 40)) self.thumbnail.setMaximumSize(QtCore.QSize(60, 40)) self.thumbnail.setText("") self.thumbnail.setPixmap(QtGui.QPixmap(":/res/no_thumb.png")) self.thumbnail.setScaledContents(False) self.thumbnail.setAlignment(QtCore.Qt.AlignCenter) self.thumbnail.setObjectName("thumbnail") self.horizontalLayout.addWidget(self.thumbnail) self.details = QtGui.QLabel(self.background) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.details.sizePolicy().hasHeightForWidth()) self.details.setSizePolicy(sizePolicy) self.details.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) self.details.setWordWrap(True) self.details.setObjectName("details") self.horizontalLayout.addWidget(self.details) self.verticalLayout.addWidget(self.background) self.retranslateUi(Item) QtCore.QMetaObject.connectSlotsByName(Item)
def __init__(self, parent): """ Constructor :param parent: QT parent object """ QtGui.QLabel.__init__(self, parent) self._play_icon = QtGui.QPixmap(":/tk_framework_qtwidgets.version_label/play_icon.png") self._play_icon_inactive = QtGui.QPixmap(":/tk_framework_qtwidgets.version_label/play_icon_inactive.png") self._sg_data = None self._hover = False self._playable = False self._interactive = True
def __init__(self, imageFileName, x=100, y=100, overImageName="pencil.png", doStart=False, parent=None): super(PicButton, self).__init__(parent) self.do_on_hover = True self.isNullPixmap = True if overImageName == None: self.do_on_hover = False if not overImageName: overImageName = "empty.png" self.overImagePath = getRessources(overImageName) self.resultPix = None self.x = x self.y = y self.setMaximumWidth(x) self.fileOnDisk = imageFileName self.attachmentPixmap = QtGui.QPixmap(imageFileName) if self.attachmentPixmap.isNull(): if doStart: self.attachmentPixmap = QtGui.QPixmap( getRessources("version.png")).scaled( 100, 100, QtCore.Qt.KeepAspectRatio) self.setMaximumWidth(100) self.setPixmap(self.attachmentPixmap) self.isNullPixmap = False self.do_on_hover = True self.createOverlayPixmap(alpha=0) self.setAlignment(QtCore.Qt.AlignLeft) else: self.attachmentPixmap = QtGui.QPixmap( getRessources("fileError.png")) self.setPixmap(self.attachmentPixmap) self.isNullPixmap = True else: self.attachmentPixmap = self.attachmentPixmap.scaled( self.x, self.y, QtCore.Qt.KeepAspectRatio) self.setPixmap(self.attachmentPixmap) self.isNullPixmap = False if self.do_on_hover: self.createOverlayPixmap() style = " QLabel { border: 2px solid gray; border-radius: 4px; padding: 2px; } " self.setStyleSheet(style)
def _set_thumbnail(self): if os.path.exists(self._thumb_path): self.treeWidget().itemWidget( self, self._column_names.index_name('thumb')) if not self.treeWidget().itemWidget( self, self._column_names.index_name('thumb')): image = QtGui.QPixmap(self._thumb_path) self.setSizeHint(self._column_names.index_name('thumb'), image.size()) thumbnail = QtGui.QLabel("", self.treeWidget()) thumbnail.setAlignment(QtCore.Qt.AlignHCenter) thumbnail.setPixmap(image) self.treeWidget().setItemWidget( self, self._column_names.index_name('thumb'), thumbnail) # add to json data ba = QtCore.QByteArray() buff = QtCore.QBuffer(ba) buff.open(QtCore.QIODevice.WriteOnly) image.save(buff, "JPG") if sys.version_info.major == 2: self._fields['data']['thumb'] = ba.toBase64().data() elif sys.version_info.major == 3: self._fields['data']['thumb'] = ba.toBase64().data( ).decode('UTF-8') # remove tmp file os.remove(self._thumb_path) elif 'thumb' in self._fields['data'].keys(): thumb_bytes = None if sys.version_info.major == 2: thumb_bytes = self._fields['data']['thumb'].encode("utf-8") elif sys.version_info.major == 3: thumb_bytes = bytes(self._fields['data']['thumb'], 'UTF-8') ba = QtCore.QByteArray.fromBase64(thumb_bytes) image = QtGui.QPixmap() image.loadFromData(ba, "JPG") thumbnail = QtGui.QLabel("", self.treeWidget()) thumbnail.setAlignment(QtCore.Qt.AlignHCenter) thumbnail.setPixmap(image) self.treeWidget().setItemWidget( self, self._column_names.index_name('thumb'), thumbnail) else: msg = "Could not find thumnail at '%s'. Failed to generate it!" % ( self._thumb_path) self._panel._app.log_error(msg)
def _get_image( self, get_img_path, get_pixmap, set_pixmap, get_parent_pixmap, default_image_path, ): """ Retrieves the image for the icon or thumbnail of this item. This method is written in a generic fashion in order to avoid complex logic duplicated inside the class. It takes a series of getter and setter methods that allow for updating the thumbnail or the icon of this item. :param function get_img_path: Function returning the path to an image on disk. :param function get_pixmap: Function returning the pixmap for the image. :param function set_pixmap: Function used to set the in-memory pixmap for the image. :param function get_parent_pixmap: Function used to get the pixmap of the parent item. :param str default_image_path: Path to the default pixmap. """ # nothing to do if running without a UI if not _is_qt_pixmap_usable(): return None # defer import until needed and to avoid issues when running without UI from sgtk.platform.qt import QtGui if get_img_path() and not get_pixmap(): # we have a path but haven't yet created the pixmap. create it try: set_pixmap(QtGui.QPixmap(get_img_path())) except Exception as e: logger.warning("%r: Could not load icon '%s': %s" % (self, get_img_path(), e)) if get_pixmap(): return get_pixmap() elif self.parent: return get_parent_pixmap() else: if default_image_path: # return default return QtGui.QPixmap(default_image_path) else: return None
def _display_value(self, value): """ Set the value displayed by the widget. :param value: The value returned by the Shotgun API to be displayed. In delegate mode, this value can also be an existing ``QPixmap`` object. """ if isinstance(value, QtGui.QPixmap): self.setPixmap(value) elif os.path.exists(value): # a local path has been set as the value. # TODO: consider when to upload to SG in non-delegate mode self._image_path = value self._value = value self.setPixmap(QtGui.QPixmap(value)) elif self._needs_download: # queue up the download in the background entity_id = None entity_type = None if self._entity: entity_id = self._entity.get("id") entity_type = self._entity.get("type") self._task_uid = self._data_retriever.request_thumbnail( value, entity_type, entity_id, self._field_name, load_image=True) self._needs_download = False self.value_changed.emit()
def _validate_image(self, path): """ Validates that the path points to an actual image. If the file can't be loaded, a warning is logged and ``None`` is returned. :param str path: Path of the image to validate. :returns: If the image was successfully loaded, the path is returned. If the image couldn't be loaded, ``None`` is returned. """ if not path: return None # We can't validate the path by creating a QPixmap, so bail out and # return the unvalidated path. if not _is_qt_pixmap_usable(): return path # defer import until needed and to avoid issues when running without UI from sgtk.platform.qt import QtGui try: icon = QtGui.QPixmap(path) except Exception as e: logger.warning( "%r: Could not load icon '%s': %s" % (self, path, e) ) return None else: return None if icon.isNull() else path
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 show_dialog(app): """ Show the main loader dialog :param app: The parent App """ # defer imports so that the app works gracefully in batch modes from .dialog import AppDialog # Create and display the splash screen splash_pix = QtGui.QPixmap(":/res/splash.png") splash = QtGui.QSplashScreen(splash_pix, QtCore.Qt.WindowStaysOnTopHint) splash.setMask(splash_pix.mask()) splash.show() QtCore.QCoreApplication.processEvents() # create the action manager for the Loader UI: from .loader_action_manager import LoaderActionManager action_manager = LoaderActionManager() # start ui ui_title = app.get_setting("title_name") w = app.engine.show_dialog(ui_title, app, AppDialog, action_manager) # attach splash screen to the main window to help GC w.__splash_screen = splash # hide splash screen after loader UI show splash.finish(w.window()) # pop up help screen if w.is_first_launch(): # wait a bit before show window QtCore.QTimer.singleShot(1400, w.show_help_popup)
def _populate_thumbnail(self, item, field, path): """ Called whenever the real thumbnail for an item exists on disk. The following execution sequence typically happens: - :class:`~PySide.QtGui.QStandardItem` is created, either through a cache load from disk or from a payload coming from the Shotgun API. - After the item has been set up with its associated Shotgun data, :meth:`_populate_default_thumbnail()` is called, allowing client code to set up a default thumbnail that will be shown while potential real thumbnail data is being loaded. - The model will now start looking for the real thumbail. - If the thumbnail is already cached on disk, :meth:`_populate_thumbnail()` is called very soon. - If there isn't a thumbnail associated, :meth:`_populate_thumbnail()` will not be called. - If there isn't a thumbnail cached, the model will asynchronously download the thumbnail from Shotgun and then (after some time) call :meth:`_populate_thumbnail()`. This method will be called for standard thumbnails if the model has been instantiated with the download_thumbs flag set to be true. It will be called for items which are associated with shotgun entities (in a tree data layout, this is typically leaf nodes). It will also be called once the data requested via _request_thumbnail_download() arrives. This method makes it possible to control how the thumbnail is applied and associated with the item. The default implementation will simply set the thumbnail to be icon of the item, but this can be altered by subclassing this method. :param item: :class:`~PySide.QtGui.QStandardItem` which is associated with the given thumbnail :param field: The Shotgun field which the thumbnail is associated with. :param path: A path on disk to the thumbnail. This is a file in jpeg format. """ # the default implementation sets the icon thumb = QtGui.QPixmap(path) item.setIcon(thumb)
def __init__(self, data, parent): """ Constructor :param parent: QT parent object :type parent: :class:`PySide.QtGui.QWidget` """ ClickableLabel.__init__(self, parent) self._bundle = sgtk.platform.current_bundle() # store shotgun data self._data = data if self._data["image"]: # a thumbnail exists for this attachment # set it up as a std event stream 254x144 chunk self.setToolTip("Click to see full attachment.<br>" "File Name: %s" % self._data["this_file"]["name"]) self.setMinimumSize(QtCore.QSize(256, 144)) self.setMaximumSize(QtCore.QSize(256, 144)) self.setText("") self.setPixmap( QtGui.QPixmap( ":/tk_framework_qtwidgets.activity_stream/rect_256x144.png" )) else: # no thumbnail for this guy self.setToolTip("Click to see full attachment.") self.setText(self._data["this_file"]["name"]) self.setStyleSheet("""QLabel { border-radius: 2px; border: 1px solid rgba(200, 200, 200, 40%); padding: 8px; }""")
def _on_worker_task_complete(self, uid, data): """ Called when the computation is complete and we should update widget with the result """ if uid != self._worker_uid: return # stop spin self._timer.stop() # set thumbnail if data.get("thumbnail"): self.ui.thumbnail.setPixmap(QtGui.QPixmap(data.get("thumbnail"))) # set light - red or green if data["up_to_date"]: icon = self._green_pixmap else: icon = self._red_pixmap self.ui.light.setPixmap(icon) # figure out if this item should be hidden if data["up_to_date"] == True and self._show_green == False: self.setVisible(False) if data["up_to_date"] == False and self._show_red == False: self.setVisible(False)
def _external_screenshot(): """ Use an external approach for grabbing a screenshot. Linux and macosx support only. :returns: Captured image :rtype: :class:`~PySide.QtGui.QPixmap` """ output_path = tempfile.NamedTemporaryFile(suffix=".png", prefix="screencapture_", delete=False).name pm = None try: # do screenshot with thread so we don't block anything screenshot_thread = ExternalCaptureThread(output_path) screenshot_thread.start() while not screenshot_thread.isFinished(): screenshot_thread.wait(100) QtGui.QApplication.processEvents() if screenshot_thread.error_message: bundle = sgtk.platform.current_bundle() bundle.log_debug("Failed to capture " "screenshot: %s" % screenshot_thread.error_message) else: # load into pixmap pm = QtGui.QPixmap(output_path) finally: # remove the temporary file if output_path and os.path.exists(output_path): os.remove(output_path) return pm
def __init__(self, parent): """ Constructor :param parent: Qt parent object """ # first, call the base class and let it do its thing. QtGui.QLineEdit.__init__(self, parent) # set up some handy references self._app = sgtk.platform.current_bundle() self.__sg_data_retriever = None self._processing_id = None self._thumb_map = {} self._default_icon = QtGui.QPixmap( ":/tk_multi_infopanel_global_search_widget/rect_512x400.png") # configure our popup completer self._completer = QtGui.QCompleter(self) self._completer.setMaxVisibleItems(10) self._completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) self._completer.setCompletionMode( QtGui.QCompleter.UnfilteredPopupCompletion) self.setCompleter(self._completer) # configure popup data source self._model = QtGui.QStandardItemModel(self) self._clear_model() self._completer.setModel(self._model) # hook up completer and trigger reload on keypress self.textEdited.connect(self._on_text_changed)
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