def mk_prj_storage_icon(self, qgs_type_storage: str) -> QLabel: """Returns a QLabel with the matching icon for the storage type. :param qgs_type_storage: storage type :type qgs_type_storage: str :return: QLabel to be set in a cellWidget :rtype: QLabel """ lbl_location_type = QLabel(self.tableWidget) lbl_location_type.setPixmap( QPixmap(icon_per_storage_type(qgs_type_storage))) lbl_location_type.setScaledContents(True) lbl_location_type.setMaximumSize(20, 20) lbl_location_type.setAlignment(Qt.AlignCenter) lbl_location_type.setTextInteractionFlags(Qt.NoTextInteraction) lbl_location_type.setToolTip(qgs_type_storage) return lbl_location_type
class PhotoViewer(QScrollArea): """ Widget for viewing images by incorporating basic navigation options. """ def __init__(self, parent=None, photo_path=""): QScrollArea.__init__(self, parent) self.setBackgroundRole(QPalette.Dark) self._printer = QPrinter() self._lbl_photo = QLabel() self._lbl_photo.setBackgroundRole(QPalette.Base) self._lbl_photo.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self._lbl_photo.setScaledContents(True) self.setWidget(self._lbl_photo) self._photo_path = photo_path self._ph_image = None self._scale_factor = 1.0 self._aspect_ratio = -1 self._create_actions() if self._photo_path: self.load_document(self._photo_path) def _create_actions(self): """ Create actions for basic image navigation. """ self._zoom_in_act = QAction( QApplication.translate("PhotoViewer", "Zoom &In (25%)"), self) self._zoom_in_act.setShortcut( QApplication.translate("PhotoViewer", "Ctrl++")) self._zoom_in_act.setEnabled(False) self._zoom_in_act.triggered.connect(self.zoom_in) self._zoom_out_act = QAction( QApplication.translate("PhotoViewer", "Zoom &Out (25%)"), self) self._zoom_out_act.setShortcut( QApplication.translate("PhotoViewer", "Ctrl+-")) self._zoom_out_act.setEnabled(False) self._zoom_out_act.triggered.connect(self.zoom_out) self._normal_size_act = QAction( QApplication.translate("PhotoViewer", "&Normal Size"), self) self._normal_size_act.setShortcut( QApplication.translate("PhotoViewer", "Ctrl+S")) self._normal_size_act.setEnabled(False) self._normal_size_act.triggered.connect(self.normal_size) self._fit_to_window_act = QAction( QApplication.translate("PhotoViewer", "&Fit to Window"), self) self._fit_to_window_act.setShortcut( QApplication.translate("PhotoViewer", "Ctrl+F")) self._fit_to_window_act.setEnabled(False) self._fit_to_window_act.setCheckable(True) self._fit_to_window_act.triggered.connect(self.fit_to_window) self._print_act = QAction( QApplication.translate("PhotoViewer", "&Print"), self) self._print_act.setShortcut( QApplication.translate("PhotoViewer", "Ctrl+P")) self._print_act.setEnabled(False) self._print_act.triggered.connect(self.print_photo) def zoom_in(self): self.scale_photo(1.25) def zoom_out(self): self.scale_photo(0.8) def normal_size(self): self._lbl_photo.adjustSize() self._scale_factor = 1.0 def fit_to_window(self): fit_to_win = self._fit_to_window_act.isChecked() self.setWidgetResizable(fit_to_win) if not fit_to_win: self.normal_size() self.update_actions() def print_photo(self): print_dialog = QPrintDialog(self._printer, self) if print_dialog.exec_() == QDialog.Accepted: painter = QPainter(self._printer) rect = painter.viewport() size = self._lbl_photo.pixmap().size() size.scale(rect.size(), Qt.KeepAspectRatio) painter.setViewport(rect.x(), rect.y(), size.width(), size.height()) painter.setWindow(self._lbl_photo.pixmap().rect()) painter.drawPixmap(0, 0, self._lbl_photo.pixmap()) def wheelEvent(self, event): """ Zoom the image based on the mouse wheel rotation action. :param event: Event containing the wheel rotation info. :type event: QWheelEvent """ degrees = event.delta() / 8 num_steps = degrees / 15 if num_steps < 0: abs_num_steps = abs(num_steps) zoom_factor = 1 + (abs_num_steps * 0.25) else: zoom_factor = 1 - (num_steps * 0.2) self.scale_photo(zoom_factor) def heightForWidth(self, width): if self._aspect_ratio != -1: return width / self._aspect_ratio else: return -1 def resizeEvent(self, event): """ Event for resizing the widget based on the pixmap's aspect ratio. :param event: Contains event parameters for the resize event. :type event: QResizeEvent """ super(PhotoViewer, self).resizeEvent(event) def update_actions(self): self._zoom_out_act.setEnabled(not self._fit_to_window_act.isChecked()) self._zoom_in_act.setEnabled(not self._fit_to_window_act.isChecked()) self._normal_size_act.setEnabled( not self._fit_to_window_act.isChecked()) def scale_photo(self, factor): """ :param factor: Value by which the image will be increased/decreased in the view. :type factor: float """ if not self._lbl_photo.pixmap().isNull(): self._scale_factor *= factor self._lbl_photo.resize(self._scale_factor * self._lbl_photo.pixmap().size()) self._adjust_scroll_bar(self.horizontalScrollBar(), factor) self._adjust_scroll_bar(self.verticalScrollBar(), factor) self._zoom_in_act.setEnabled(self._scale_factor < 3.0) self._zoom_out_act.setEnabled(self._scale_factor > 0.333) def _adjust_scroll_bar(self, scroll_bar, factor): scroll_bar.setValue( int(factor * scroll_bar.value() + ((factor - 1) * scroll_bar.pageStep() / 2))) def load_document(self, photo_path): if photo_path: self._ph_image = QImage(photo_path) if self._ph_image.isNull(): return False self._photo_path = photo_path ph_pixmap = QPixmap.fromImage(self._ph_image) self._lbl_photo.setPixmap(ph_pixmap) self._scale_factor = 1.0 self._aspect_ratio = ph_pixmap.width() / ph_pixmap.height() self._fit_to_window_act.setEnabled(True) self._print_act.setEnabled(True) self._fit_to_window_act.trigger() self.update_actions() return ph_pixmap return True def photo_location(self): """ :returns: Absolute path of the photo in the central document repository. """ return self._photo_path def set_actions(self, menu): """ Add custom actions to the sub-window menu """ menu.addSeparator() menu.addAction(self._zoom_in_act) menu.addAction(self._zoom_out_act) menu.addAction(self._normal_size_act) menu.addAction(self._fit_to_window_act) menu.addSeparator() menu.addAction(self._print_act)