class ImageViewer(QWidget): """A custom widget to display an image in Gui.""" # Inspired by : # https://doc.qt.io/qt-6/qtwidgets-widgets-imageviewer-example.html # https://code.qt.io/cgit/pyside/pyside-setup.git/tree/examples/widgets/imageviewer def __init__(self, parent=None): """Initialize Widget.""" super().__init__(parent) self.setLayout(QVBoxLayout()) self.imglabel = QLabel() self.imglabel.setBackgroundRole(QPalette.Base) self.imglabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.imglabel.setScaledContents(True) # Resize pixmap along with label self.imglabel.setAlignment(Qt.AlignCenter) self.imglabel.setText("(No image yet)") self.namelabel = QLabel() self.scrollarea = QScrollArea() self.scrollarea.setWidget(self.imglabel) self.scrollarea.setWidgetResizable(False) self.scrollarea.setAlignment(Qt.AlignCenter) self.layout().addWidget(self.scrollarea) self.layout().addWidget(self.namelabel) self.scale_factor = 1.0 self._initial_size = QSize(0, 0) self._img_path = "" self.setContextMenuPolicy(Qt.CustomContextMenu) # pylint: disable=no-member self.customContextMenuRequested.connect(self.show_context_menu) self.menu = QMenu() self.add_actions_to_menu(self.menu) def add_actions_to_menu(self, menu): """Add widget actions to a given menu. Args: menu -- the menu to add the actions (QMenu) """ zoom_in_act = menu.addAction("Zoom In (25%)") zoom_in_act.triggered.connect(self.zoom_in) zoom_out_act = menu.addAction("Zoom Out (25%)") zoom_out_act.triggered.connect(self.zoom_out) zoom_normal_act = menu.addAction("Normal Size") zoom_normal_act.triggered.connect(self.normal_size) menu.addSeparator() copy_filename_act = menu.addAction("Copy Image to Clipboard") copy_filename_act.triggered.connect(self.copy_image) copy_filename_act = menu.addAction("Copy Filename to Clipboard") copy_filename_act.triggered.connect(self.copy_filename) def load_image(self, img_path): """Load an image in widget from a file. Args: img_path -- Path of image file to load (str) """ img_path = str(img_path) pixmap = QPixmap(img_path) self.imglabel.setPixmap(pixmap) self.imglabel.resize(pixmap.size()) self.namelabel.setText(f"File: {img_path}") self._img_path = img_path self._initial_size = pixmap.size() def resize_image(self, new_size=None): """Resize embedded image to target size. Args: new_size -- target size to resize image to (QSize) """ if not new_size: new_size = self._initial_size self.scale_factor = 1.0 new_size = QSize(new_size) self.imglabel.setMinimumSize(new_size) self.imglabel.setMaximumSize(new_size) def scale_image(self, factor): """Rescale embedded image applying a factor. Factor is applied relatively to current scale. Args: factor -- Factor to apply (float) """ self.scale_factor *= float(factor) new_size = self.scale_factor * self._initial_size self.resize_image(new_size) @Slot() def zoom_in(self): """Zoom embedded image in (slot).""" self.scale_image(1.25) @Slot() def zoom_out(self): """Zoom embedded image out (slot).""" self.scale_image(0.8) @Slot() def normal_size(self): """Set embedded image scale to 1:1 (slot).""" self.resize_image() @Slot() def copy_filename(self): """Copy file name to clipboard (slot).""" QGuiApplication.clipboard().setText(self._img_path) @Slot() def copy_image(self): """Copy embedded image to clipboard (slot).""" QGuiApplication.clipboard().setImage(self.imglabel.pixmap().toImage()) @Slot(QPoint) def show_context_menu(self, pos): """Show context menu.""" self.menu.exec_(self.mapToGlobal(pos))
class QDataViewer(QWidget): def __init__(self): QWidget.__init__(self) # Layout Init. self.setGeometry(300, 300, 600, 100) self.setFixedSize(self.width(), self.height()) self.setWindowTitle('ArganRecogn') # Attributes self.filename = "" self.upload_destination = "" self.layout = QVBoxLayout() self.imageLabel = QLabel() self.imageLabel.setBackgroundRole(QPalette.Base) self.imageLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.imageLabel.setScaledContents(True) self.labels_panel = LabelsPanel() self.buttons_panel = ButtonsPanel() def add_button(self, text, action): self.buttons_panel.add_button(text, action) def add_label(self, text): return self.labels_panel.add_label(text) @staticmethod def show_alert_dialog(exception): msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText("Something wrong occurred") msg.setInformativeText(str(exception.message)) msg.setWindowTitle("Something wrong occurred") msg.setDetailedText("The details are as follows:\n" + exception.message) print "The details are as follows:\n" + exception.message msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) msg.buttonClicked.connect(QDataViewer.msgbtn) retval = msg.exec_() print "value of pressed message box button:", retval @staticmethod def show_dialog(message, title): msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText(title) msg.setInformativeText(message) msg.setWindowTitle("Something wrong occurred") msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) msg.buttonClicked.connect(QDataViewer.msgbtn) retval = msg.exec_() print "value of pressed message box button:", retval @staticmethod def msgbtn(i): print "Button pressed is:", i.text() def build(self): self.labels_panel.build() self.buttons_panel.build() self.layout.addWidget(self.labels_panel) self.layout.addWidget(self.buttons_panel) self.setLayout(self.layout)