def _set_icon_label(self, icon_info, icon_label): image, mime, file_info = icon_info pixmap = None if image: pixmap = QPixmap(self.FILE_LIST_ICON_SIZE, self.FILE_LIST_ICON_SIZE) pixmap.convertFromImage(image) elif mime: icon = self._get_icon(mime) if icon: pixmap = icon.pixmap( self.FILE_LIST_ICON_SIZE, self.FILE_LIST_ICON_SIZE) if not pixmap or pixmap.isNull(): icon = QFileIconProvider().icon(file_info) pixmap = icon.pixmap( self.FILE_LIST_ICON_SIZE, self.FILE_LIST_ICON_SIZE) if pixmap and not pixmap.isNull(): icon_label.setPixmap(pixmap) icon_label.setScaledContents(True) icon_label.setFixedSize( self.FILE_LIST_ICON_SIZE, self.FILE_LIST_ICON_SIZE) icon_label.setAlignment(Qt.AlignCenter)
def setImage( self, pixmap: QtGui.QPixmap ) -> None: if not pixmap.isNull(): self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag) else: self.setDragMode(QtWidgets.QGraphicsView.NoDrag) scene = QtWidgets.QGraphicsScene(parent=self) mode = QtCore.Qt.TransformationMode.SmoothTransformation scene.addPixmap(pixmap).setTransformationMode(mode) self.setScene(scene) self.zoom = 0 self.fitToScreen()
def __init__(self, listview, first, second, third, icon): """ :param listview: The parent ListView. :param first: The first line of text. :param second: The second line of text. :param third: The third line of text. :param icon: The full path to the icon. """ QListWidgetItem.__init__(self, listview, type=QListWidgetItem.UserType) self.widget = QWidget() # Vertical box (texts) self.vbox = QVBoxLayout() self.first_line = QLabel(first) self.first_line.setWordWrap(True) self.second_line = QLabel(second) self.second_line.setWordWrap(True) self.third_line = QLabel(third) self.third_line.setWordWrap(True) for widget in [self.first_line, self.second_line, self.third_line]: self.vbox.addWidget(widget) # Horizontal box (icon + vertical box) self.hbox = QHBoxLayout() self.icon = QLabel() pixmap = QPixmap(icon) if not pixmap.isNull(): pixmap = pixmap.scaled(CustomItem.icon_size) self.icon.setPixmap(pixmap) self.hbox.addWidget(self.icon, 0) self.hbox.addLayout(self.vbox, 1) self.widget.setLayout(self.hbox) # Set the widget as the content of the list item self.setSizeHint(self.widget.sizeHint()) listview.setItemWidget(self, self.widget) self.first_line.setStyleSheet('''font-weight: bold;''') # self.comment.setStyleSheet('''''') self.third_line.setStyleSheet('''font-style: italic;''')
def fileDropped(self, path): path = str(path) name, ext = os.path.splitext(path) ext = ext[1:] if not ext in self.supportedFormats: QMessageBox.warning(self, "Warning", "The dropped file is not supported") return pixmap = QPixmap(path) if pixmap.isNull(): QMessageBox.warning(self, "Warning", "Can't load the image") return if self.path: self.fileWatcher.removePath(self.path) self.path = path self.fileWatcher.addPath(self.path) self.pixmapWidget.setPixmap(pixmap) self.generateAndExportButton.setEnabled(True) self.setTitle() self.activateWindow()
def update_thumbnail(self): if self.path != "": pixmap = QPixmap(self.path) if pixmap.isNull(): criticalMessageBox = QMessageBox() criticalMessageBox.critical( None, "Invalid Image", f"Image at path {self.path} could not be found.", criticalMessageBox.Close, ) else: aspectRatio = pixmap.size().width() / pixmap.size().height() if aspectRatio > 1.78: scaledPixmap = pixmap.scaledToWidth( self.thumbnail.size().width()) else: scaledPixmap = pixmap.scaledToHeight( self.thumbnail.size().height()) self.thumbnail.setPixmap(scaledPixmap)
def testQPixmapConstructor(self): label = QLabel() pixmap1 = QPixmap(xpm) self.assertFalse(pixmap1.isNull()) self.assertEqual(pixmap1.width(), 27) self.assertEqual(pixmap1.height(), 22)
class PhotoEditor(QMainWindow): #Ok def __init__(self): super().__init__() self.iniciaUI() def iniciaUI(self): """ Inicializa a janela e mostra seu conteuda na tela """ self.setFixedSize(650, 650) #self.setGeometry(100,100, 400, 230) self.setWindowTitle("Photo Editor") self.centerMainWindow() self.createToolsDockWidget() self.createMenu() self.createToolBar() self.photoEditorWidgets() self.show() def centerMainWindow(self): #Ok """ Use a classe QDesktopWidget para acessar informações sobre sua tela e use-a para centralizar a janela do aplicativo. """ desktop = QDesktopWidget().screenGeometry() screen_width = desktop.width() screen_height = desktop.height() self.move((screen_width - self.width()) / 2, (screen_height - self.height()) / 2) def createMenu(self): #Ok """ Criar menu para editor de fotos """ self.abre_act = QAction(QIcon('Imagens/open_file.png'), "Abrir", self) self.abre_act.setShortcut('Ctrl+O') self.abre_act.setStatusTip('Abrir uma nova imagem') self.abre_act.triggered.connect(self.openImage) self.salv_act = QAction(QIcon('Imagens/save_file.png'), 'Salvar', self) self.salv_act.setShortcut('Ctrl+S') self.salv_act.setStatusTip('Salvar imagem') self.salv_act.triggered.connect(self.saveToFile) self.prnt_act = QAction(QIcon('Imagens/print.png'), "Imprimir", self) self.prnt_act.setShortcut('Ctrl+P') self.prnt_act.setStatusTip('Imprimir imagem') self.prnt_act.triggered.connect(self.printImage) self.prnt_act.setEnabled(False) self.sair_act = QAction(QIcon('Imagens/exit.png'), 'Sair', self) self.sair_act.setShortcut('Ctrl+Q') self.sair_act.setStatusTip('Sair do programa') self.sair_act.triggered.connect(self.close) self.rt90_act = QAction("Girar 90°", self) self.rt90_act.setStatusTip('Girar imagem 90 ° no sentido horário') self.rt90_act.triggered.connect(self.rotateImage90) self.rt180_act = QAction("Girar 180°", self) self.rt180_act.setStatusTip('Girar imagem 180° no sentido horário') self.rt180_act.triggered.connect(self.rotateImage180) self.flph_act = QAction("Espelhar na Horizontal", self) self.flph_act.setStatusTip('Espelhar imagem no eixo horizontal') self.flph_act.triggered.connect(self.flipImageHorizontal) self.flpv_act = QAction("Espelhar na Vertical", self) self.flpv_act.setStatusTip('Espelhar imagem no eixo vertical') self.flpv_act.triggered.connect(self.flipImageVertical) self.redm_act = QAction("Redimensionar metade", self) self.redm_act.setStatusTip( 'Redimensionar imagem para metade do tamanho original') self.redm_act.triggered.connect(self.resizeImageHalf) self.limp_act = QAction(QIcon('Imagens/clear.png'), "Limpar Imagem", self) self.limp_act.setShortcut("Ctrl+D") self.limp_act.setStatusTip('Limpar a imagem atual') self.limp_act.triggered.connect(self.clearImage) menu_bar = self.menuBar() menu_bar.setNativeMenuBar(False) arqv_menu = menu_bar.addMenu('Arquivo') arqv_menu.addAction(self.abre_act) arqv_menu.addAction(self.salv_act) arqv_menu.addSeparator() arqv_menu.addAction(self.prnt_act) arqv_menu.addSeparator() arqv_menu.addAction(self.sair_act) edit_menu = menu_bar.addMenu('Editar') edit_menu.addAction(self.rt90_act) edit_menu.addAction(self.rt180_act) edit_menu.addSeparator() edit_menu.addAction(self.flph_act) edit_menu.addAction(self.flpv_act) edit_menu.addSeparator() edit_menu.addAction(self.redm_act) edit_menu.addSeparator() edit_menu.addAction(self.limp_act) #??????????????????? view_menu = menu_bar.addMenu('Exibir') view_menu.addAction(self.toggle_dock_tools_act) self.setStatusBar(QStatusBar(self)) def openImage(self): #Ok """ Abrir um arquivo de imagem e exiba seu conteúdo no label. Exibir mensagem de erro se a imagem não puder ser aberta. """ arq_img, _ = QFileDialog.getOpenFileName( self, "Abrir Imagem", "", "Arquivos JPG (*.jpeg *.jpg );;Arquivos PNG (*.png)\ ;;Arquivos Bitmap (*.bmp);;Arquivos GIF (*.gif)") if arq_img: self.img = QPixmap(arq_img) self.img_lbl.setPixmap( self.img.scaled(self.img_lbl.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) else: QMessageBox.information(self, "Erro", "Não é possível abrir imagem.", QMessageBox.Ok) self.prnt_act.setEnabled(True) def saveToFile(self): #Ok """ Salvar a imagem. Exibir mensagem de erro se a imagem não puder ser salva. """ arq_img, _ = QFileDialog.getSaveFileName( self, "Salvar Imagem", "", "Arquivos JPG (*.jpeg *.jpg );;Arquivos PNG (*.png)\ ;;Arquivos Bitmap (*.bmp);;Arquivos GIF (*.gif)") if arq_img and self.img.isNull() == False: self.img.save(image_file) else: QMessageBox.information(self, "Não é possível salvar imagem.", QMessageBox.Ok) def printImage(self): #Ok """Imprimir Imagem """ printer = QPrinter() printer.setOutputFormat(QPrinter.NativeFormat) prnt_dlg = QPrintDialog(printer) if (prnt_dlg.exec_() == QPrintDialog.Accepted): painter = QPainter() painter.begin(printer) rect = QRect(painter.viewport()) size = QSize(self.img_lbl.pixmap().size()) size.scale(rect.size(), Qt.KeepAspectRatio) painter.setViewport(rect.x(), rect.y(), size.width(), size.height()) painter.setWindow(self.img_lbl.pixmap().rect()) painter.drawPixmap(0, 0, self.img_lbl.pixmap()) painter.end() def rotateImage90(self): #Ok """ Girar imagem 90° no sentido horário """ if self.img.isNull() == False: transform90 = QTransform().rotate(90) pixmap = QPixmap(self.img) rotated = pixmap.transformed(transform90, mode=Qt.SmoothTransformation) self.img_lbl.setPixmap( rotated.scaled(self.img_lbl.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) self.img = QPixmap(rotated) self.img_lbl.repaint() # repaint the child widget else: # No image to rotate pass def rotateImage180(self): #Ok """ Girar imagem 180° no sentido horário """ if self.img.isNull() == False: transform180 = QTransform().rotate(180) pixmap = QPixmap(self.img) rotated = pixmap.transformed(transform180, mode=Qt.SmoothTransformation) self.img_lbl.setPixmap( rotated.scaled(self.img_lbl.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) self.img = QPixmap(rotated) self.img_label.repaint() # repaint the child widget else: # No image to rotate pass def flipImageHorizontal(self): #Ok """ Espelhar a imagem no eixo horizontal """ if self.img.isNull() == False: flip_h = QTransform().scale(-1, 1) pixmap = QPixmap(self.img) flipped = pixmap.transformed(flip_h) self.img_lbl.setPixmap( flipped.scaled(self.img_lbl.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) self.img = QPixmap(flipped) self.img_lbl.repaint() else: pass def flipImageVertical(self): #Ok """ Espelhar a imagem no eixo vertical """ if self.img.isNull() == False: flip_v = QTransform().scale(1, -1) pixmap = QPixmap(self.img) flipped = pixmap.transformed(flip_v) self.img_lbl.setPixmap( flipped.scaled(self.img_lbl.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) self.img = QPixmap(flipped) self.img_lbl.repaint() else: pass def resizeImageHalf(self): #Ok """ Redimensione a imagem para a metade do tamanho atual. """ if self.img.isNull() == False: resize = QTransform().scale(0.5, 0.5) pixmap = QPixmap(self.img) resized = pixmap.transformed(resize) self.img_lbl.setPixmap( resized.scaled(self.img_lbl.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) self.img = QPixmap(resized) self.img_lbl.repaint() else: pass def clearImage(self): #Ok """ Limpar a imagem atual no widget QLabel """ self.img_lbl.clear() self.img = QPixmap() def createToolBar(self): #Ok """ Criar barra de ferramentas para editor de fotos """ tool_bar = QToolBar("Barra de Ferramentas do Editor de Fotos") tool_bar.setIconSize(QSize(24, 24)) self.addToolBar(tool_bar) tool_bar.addAction(self.abre_act) tool_bar.addAction(self.salv_act) tool_bar.addAction(self.prnt_act) tool_bar.addAction(self.limp_act) tool_bar.addSeparator() tool_bar.addAction(self.sair_act) def createToolsDockWidget(self): #Ok """ Use o menu Exibir -> Editar Ferramentas de Imagem e clique no widget dock para ligar ou desligar. O dock de ferramentas pode ser colocado à esquerda ou à direita da janela principal. """ self.dock_tools_view = QDockWidget() self.dock_tools_view.setWindowTitle("Ferramentas Edição de Imagem") self.dock_tools_view.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.img_tool = QWidget() self.rt90_btn = QPushButton("Girar 90°") self.rt90_btn.setMinimumSize(QSize(130, 40)) self.rt90_btn.setStatusTip('Girar imagem 90° no sentido horário') self.rt90_btn.clicked.connect(self.rotateImage90) self.rt180_btn = QPushButton("Girar 180°") self.rt180_btn.setMinimumSize(QSize(130, 40)) self.rt180_btn.setStatusTip('Girar imagem 180° no sentido horário') self.rt180_btn.clicked.connect(self.rotateImage180) self.flph_btn = QPushButton("Espelhar na Horizontal") self.flph_btn.setMinimumSize(QSize(130, 40)) self.flph_btn.setStatusTip('Espelhar imagem no eixo horizontal') self.flph_btn.clicked.connect(self.flipImageHorizontal) self.flpv_btn = QPushButton("Espelhar na Vertical") self.flpv_btn.setMinimumSize(QSize(130, 40)) self.flpv_btn.setStatusTip('Espelhar imagem no eixo vertical') self.flpv_btn.clicked.connect(self.flipImageVertical) self.redm_btn = QPushButton("Redimensionar metade") self.redm_btn.setMinimumSize(QSize(130, 40)) self.redm_btn.setStatusTip( 'Redimensionar imagem para metade do tamanho original') self.redm_btn.clicked.connect(self.resizeImageHalf) vbox = QVBoxLayout() vbox.addWidget(self.rt90_btn) vbox.addWidget(self.rt180_btn) vbox.addStretch(1) vbox.addWidget(self.flph_btn) vbox.addWidget(self.flpv_btn) vbox.addStretch(1) vbox.addWidget(self.redm_btn) vbox.addStretch(6) self.img_tool.setLayout(vbox) self.dock_tools_view.setWidget(self.img_tool) self.addDockWidget(Qt.RightDockWidgetArea, self.dock_tools_view) self.toggle_dock_tools_act = self.dock_tools_view.toggleViewAction() def photoEditorWidgets(self): #Ok """ Configurar instâncias de widgets para editor de fotos """ self.img = QPixmap() self.img_lbl = QLabel() self.img_lbl.setAlignment(Qt.AlignCenter) self.img_lbl.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored) self.setCentralWidget(self.img_lbl)
def __init__(self, data, title="", comment="", icon=None, parent=None, apply=None, ok=None, cancel=None, result=None, outfile=None, type=None, scrollbar=None, background_color=None, widget_color=None): QDialog.__init__(self, parent) #self.setWindowModality(Qt.ApplicationModal) self.setWindowFlags((self.windowFlags() & ~Qt.WindowContextHelpButtonHint) ) # djb added # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.type = type self.title = title self.ok = ok self.cancel = cancel self.apply_ = None self.apply_callback = None if callable(apply): self.apply_callback = apply elif isinstance(apply, (list, tuple)): self.apply_, self.apply_callback = apply elif apply is not None: raise AssertionError("`apply` argument must be either a function or tuple ('Apply label', apply_callback)") self.outfile = outfile self.result = result if self.result in ['OrderedDict', 'JSON']: global OrderedDict from collections import OrderedDict if self.result == 'JSON': global json import json elif self.result == 'XML': global ET import xml.etree.ElementTree as ET self.widget_color = widget_color if background_color: style = "FormDialog {background-color:" + background_color + ";}" self.setStyleSheet(style) # Form if isinstance(data[0][0], (list, tuple)): self.formwidget = FormTabWidget(data, comment=comment,parent=self) elif len(data[0])==3: self.formwidget = FormComboWidget(data, comment=comment,parent=self) else: self.formwidget = FormWidget(data, comment=comment,parent=self) layout = QVBoxLayout() if scrollbar == True: scroll = QScrollArea(parent=self) scroll.setWidgetResizable(True) scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) scroll.setWidget(self.formwidget) layout.addWidget(scroll) else: layout.addWidget(self.formwidget) self.float_fields = [] self.required_fields = [] self.formwidget.setup() # Button box self.bbox = bbox = QDialogButtonBox() if self.ok == True: bbox.addButton(QDialogButtonBox.Ok) elif self.ok: ok_btn = QPushButton(self.ok) bbox.addButton(ok_btn, QDialogButtonBox.AcceptRole) if self.cancel == True: bbox.addButton(QDialogButtonBox.Cancel) elif self.cancel: cancel_btn = QPushButton(self.cancel) bbox.addButton(cancel_btn, QDialogButtonBox.RejectRole) if self.apply_callback is not None: if self.apply_: apply_btn = QPushButton(self.apply_) bbox.addButton(apply_btn, QDialogButtonBox.ApplyRole) else: apply_btn = bbox.addButton(QDialogButtonBox.Apply) if SIGNAL is None: apply_btn.clicked.connect(self.apply) else: self.connect(apply_btn, SIGNAL("clicked()"), self.apply) if SIGNAL is None: if self.ok: bbox.accepted.connect(self.accept) if self.cancel: bbox.rejected.connect(self.reject) else: if self.ok: self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()")) if self.cancel: self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()")) layout.addWidget(bbox) self.required_valid() self.setLayout(layout) self.setWindowTitle(self.title) if not isinstance(icon, QIcon): icon = QPixmap(icon) if icon.isNull(): icon = QWidget().style().standardIcon(QStyle.SP_MessageBoxQuestion) self.setWindowIcon(icon)
def object_pixmap(object_class_name): """An object pixmap defined for `object_class_name` if any, or a generic one if none.""" pixmap = QPixmap(":/object_class_icons/{0}.png".format(object_class_name)) if pixmap.isNull(): pixmap = QPixmap(":/icons/object_icon.png") return pixmap
class MandelbrotWidget(QWidget): def __init__(self, parent=None): super(MandelbrotWidget, self).__init__(parent) self.thread = RenderThread() self.pixmap = QPixmap() self.pixmapOffset = QPoint() self.lastDragPos = QPoint() self.centerX = DefaultCenterX self.centerY = DefaultCenterY self.pixmapScale = DefaultScale self.curScale = DefaultScale self.thread.renderedImage.connect(self.updatePixmap) self.setWindowTitle("Mandelbrot") self.setCursor(Qt.CrossCursor) self.resize(550, 400) def paintEvent(self, event): painter = QPainter(self) painter.fillRect(self.rect(), Qt.black) if self.pixmap.isNull(): painter.setPen(Qt.white) painter.drawText(self.rect(), Qt.AlignCenter, "Rendering initial image, please wait...") return if self.curScale == self.pixmapScale: painter.drawPixmap(self.pixmapOffset, self.pixmap) else: scaleFactor = self.pixmapScale / self.curScale newWidth = int(self.pixmap.width() * scaleFactor) newHeight = int(self.pixmap.height() * scaleFactor) newX = self.pixmapOffset.x() + (self.pixmap.width() - newWidth) / 2 newY = self.pixmapOffset.y() + (self.pixmap.height() - newHeight) / 2 painter.save() painter.translate(newX, newY) painter.scale(scaleFactor, scaleFactor) exposed, _ = painter.matrix().inverted() exposed = exposed.mapRect(self.rect()).adjusted(-1, -1, 1, 1) painter.drawPixmap(exposed, self.pixmap, exposed) painter.restore() text = "Use mouse wheel or the '+' and '-' keys to zoom. Press and " \ "hold left mouse button to scroll." metrics = painter.fontMetrics() textWidth = metrics.width(text) painter.setPen(Qt.NoPen) painter.setBrush(QColor(0, 0, 0, 127)) painter.drawRect((self.width() - textWidth) / 2 - 5, 0, textWidth + 10, metrics.lineSpacing() + 5) painter.setPen(Qt.white) painter.drawText((self.width() - textWidth) / 2, metrics.leading() + metrics.ascent(), text) def resizeEvent(self, event): self.thread.render(self.centerX, self.centerY, self.curScale, self.size()) def keyPressEvent(self, event): if event.key() == Qt.Key_Plus: self.zoom(ZoomInFactor) elif event.key() == Qt.Key_Minus: self.zoom(ZoomOutFactor) elif event.key() == Qt.Key_Left: self.scroll(-ScrollStep, 0) elif event.key() == Qt.Key_Right: self.scroll(+ScrollStep, 0) elif event.key() == Qt.Key_Down: self.scroll(0, -ScrollStep) elif event.key() == Qt.Key_Up: self.scroll(0, +ScrollStep) else: super(MandelbrotWidget, self).keyPressEvent(event) def wheelEvent(self, event): numDegrees = event.angleDelta().y() / 8 numSteps = numDegrees / 15.0 self.zoom(pow(ZoomInFactor, numSteps)) def mousePressEvent(self, event): if event.buttons() == Qt.LeftButton: self.lastDragPos = QPoint(event.pos()) def mouseMoveEvent(self, event): if event.buttons() & Qt.LeftButton: self.pixmapOffset += event.pos() - self.lastDragPos self.lastDragPos = QPoint(event.pos()) self.update() def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: self.pixmapOffset += event.pos() - self.lastDragPos self.lastDragPos = QPoint() deltaX = (self.width() - self.pixmap.width()) / 2 - self.pixmapOffset.x() deltaY = (self.height() - self.pixmap.height()) / 2 - self.pixmapOffset.y() self.scroll(deltaX, deltaY) def updatePixmap(self, image, scaleFactor): if not self.lastDragPos.isNull(): return self.pixmap = QPixmap.fromImage(image) self.pixmapOffset = QPoint() self.lastDragPosition = QPoint() self.pixmapScale = scaleFactor self.update() def zoom(self, zoomFactor): self.curScale *= zoomFactor self.update() self.thread.render(self.centerX, self.centerY, self.curScale, self.size()) def scroll(self, deltaX, deltaY): self.centerX += deltaX * self.curScale self.centerY += deltaY * self.curScale self.update() self.thread.render(self.centerX, self.centerY, self.curScale, self.size())
def testImage(self): app = QApplication([]) image = QPixmap(":image") self.assertFalse(image.isNull())
def img_viewer(self, undo_op=False): if self.idx_curr_file >= len(self.file_paths) or len( self.file_paths) == 0: self.infos_dict['fd_info'] = "No img" self.ui.status_bar.showMessage(self.infos_dict['fd_info']) self.ui.img_show_label.setText(" ") else: while self.idx_curr_file < len(self.file_paths): QApplication.processEvents() img_path = self.file_paths[self.idx_curr_file] if img_path.endswith(".gif"): movie = QMovie(img_path) self.ui.img_show_label.setMovie(movie) movie.start() self.infos_dict['fd_info'] = "%d/%d: %s" % ( self.idx_curr_file, len(self.file_paths), self.file_paths[self.idx_curr_file]) self.ui.status_bar.showMessage(self.infos_dict['fd_info']) break pixmap = QPixmap(img_path) if not pixmap.isNull(): try: image = Image.open(img_path) rotated_flag = False angle = 0 for orientation in ExifTags.TAGS.keys(): if ExifTags.TAGS[orientation] == 'Orientation': break exif = dict(image._getexif().items()) print(img_path, " exif: ", exif[orientation]) if exif[orientation] == 3: angle = 180 rotated_flag = True elif exif[orientation] == 6: angle = 270 rotated_flag = True elif exif[orientation] == 8: angle = 90 rotated_flag = True if rotated_flag: pixmap = pixmap.transformed( QTransform().rotate(-angle)) image = image.rotate(angle, expand=True) image.save(img_path) image.close() except (AttributeError, KeyError, IndexError): # cases: image don't have getexif pass max_h = self.ui.img_show_label.height() max_w = self.ui.img_show_label.width() if max_h > self.configurator.using_conf_dict[ 'image default display size'][0]: max_h = self.configurator.using_conf_dict[ 'image default display size'][0] if max_w > self.configurator.using_conf_dict[ 'image default display size'][1]: max_w = self.configurator.using_conf_dict[ 'image default display size'][1] self.ui.img_show_label.setPixmap( pixmap.scaled(max_w, max_h, aspectMode=Qt.KeepAspectRatio)) # QApplication.processEvents() self.infos_dict['fd_info'] = "%d/%d: %s" % ( self.idx_curr_file, len(self.file_paths), self.file_paths[self.idx_curr_file]) self.ui.status_bar.showMessage(self.infos_dict['fd_info']) break elif not undo_op: self.idx_curr_file = self.idx_curr_file + 1 else: self.idx_curr_file = self.idx_curr_file - 1 if self.idx_curr_file < 0: self.idx_curr_file = 0 break
class ColorPanelHSB(QWidget): """ 颜色选取面板 作者:feiyangqingyun(QQ:517216493) 2017-11-17 译者:sunchuquin(QQ:1715216365) 2021-07-03 1. 可设置当前百分比,用于控制指针大小 2. 可设置边框宽度 3. 可设置边框颜色 4. 可设置指针颜色 """ colorChanged = Signal(QColor, float, float) # color, hue, sat def __init__(self, parent: QWidget = None): super(ColorPanelHSB, self).__init__(parent) self.__percent: int = 100 # 当前百分比 self.__borderWidth: int = 10 # 边框宽度 self.__borderColor: QColor = QColor(0, 0, 0, 50) # 边框颜色 self.__cursorColor: QColor = QColor(0, 0, 0) # 鼠标按下处的文字形状颜色 self.__color: QColor = QColor(255, 0, 0) # 鼠标按下处的颜色 self.__hue: float = 0 # hue值 self.__sat: float = 100 # sat值 self.__lastPos: QPoint = QPoint(self.__borderWidth, self.__borderWidth) # 最后鼠标按下去的坐标 self.__bgPix: QPixmap = QPixmap() # 背景颜色图片 def showEvent(self, event: QShowEvent = None) -> None: width: int = self.width() height: int = self.height() # 首次显示记住当前背景截图,用于获取颜色值 self.__bgPix = QPixmap(width, height) self.__bgPix.fill(Qt.transparent) painter: QPainter = QPainter() painter.begin(self.__bgPix) colorStart: QColor = QColor() colorCenter: QColor = QColor() colorEnd: QColor = QColor() for i in range(width): colorStart.setHslF(i / width, 1, 0) colorCenter.setHslF(i / width, 1, 0.5) colorEnd.setHslF(i / width, 1, 1) linearGradient: QLinearGradient = QLinearGradient() linearGradient.setStart(QPointF(i, -height)) linearGradient.setFinalStop(QPointF(i, height)) linearGradient.setColorAt(0.0, colorStart) linearGradient.setColorAt(0.5, colorCenter) linearGradient.setColorAt(1.0, colorEnd) painter.setPen(QPen(linearGradient, 1)) painter.drawLine(QPointF(i, 0), QPointF(i, height)) painter.end() def resizeEvent(self, event: QResizeEvent = None) -> None: self.showEvent() def mousePressEvent(self, event: QMouseEvent = None) -> None: self.mouseMoveEvent(event) def mouseMoveEvent(self, event: QMouseEvent = None) -> None: x: int = event.pos().x() y: int = event.pos().y() # 矫正X轴的偏差 if x <= self.__borderWidth: x = self.__borderWidth elif x >= self.width() - self.__borderWidth: x = self.width() - self.__borderWidth # 矫正Y轴的偏差 if y <= self.__borderWidth: y = self.__borderWidth elif y >= self.height() - self.__borderWidth: y = self.height() - self.__borderWidth # 指针必须在范围内 self.__lastPos = QPoint(x, y) # 获取当前坐标处的颜色值 self.__color = QColor(self.__bgPix.toImage().pixel(self.__lastPos)) # X坐标所在360分比为hue值 self.__hue = ((x - self.__borderWidth) / (self.width() - self.__borderWidth * 2)) * 360 # Y坐标所在高度的100分比sat值 self.__sat = 100 - ((y - self.__borderWidth) / (self.height() - self.__borderWidth * 2) * 100) self.update() self.colorChanged.emit(self.__color, self.__hue, self.__sat) def paintEvent(self, event: QPaintEvent = None) -> None: # 绘制准备工作,启用反锯齿 painter: QPainter = QPainter(self) painter.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing) # 绘制背景颜色 self.drawBg(painter) # 绘制按下出的形状 self.drawCursor(painter) # 绘制边框 self.drawBorder(painter) def drawBg(self, painter: QPainter = None) -> None: painter.save() if not self.__bgPix.isNull(): painter.drawPixmap(0, 0, self.__bgPix) painter.restore() def drawCursor(self, painter: QPainter = None) -> None: painter.save() painter.setPen(self.__cursorColor) text: str = "+" # 根据右侧的百分比显示字体大小 textFont: QFont = QFont() size: int = int(20 + (35 * self.__percent / 100)) textFont.setPixelSize(size) # 计算文字的宽度高度,自动移到鼠标按下处的中心点 fm: QFontMetrics = QFontMetrics(textFont) textWidth: int = fm.width(text) textHeight: int = fm.height() textPoint: QPoint = self.__lastPos - QPoint(textWidth // 2, -(textHeight // 4)) path: QPainterPath = QPainterPath() path.addText(textPoint, textFont, text) painter.drawPath(path) painter.restore() def drawBorder(self, painter: QPainter = None) -> None: painter.save() width: int = self.width() height: int = self.height() offset: int = self.__borderWidth pen: QPen = QPen() pen.setWidth(offset) pen.setColor(self.__borderColor) pen.setCapStyle(Qt.RoundCap) pen.setJoinStyle(Qt.MiterJoin) painter.setPen(pen) painter.setBrush(Qt.NoBrush) painter.drawRect(offset // 2, offset // 2, width - offset, height - offset) painter.restore() def sizeHint(self) -> QSize: return QSize(500, 350) def minimumSizeHint(self) -> QSize: return QSize(100, 60) @property def percent(self) -> int: return self.__percent @percent.setter def percent(self, n_percent: int) -> None: if self.__percent == n_percent: return self.__percent = n_percent self.update() @property def borderColor(self) -> QColor: return self.__borderColor @borderColor.setter def borderColor(self, border_color: QColor) -> None: if self.__borderColor == border_color: return self.__borderColor = border_color self.update() @property def cursorColor(self) -> QColor: return self.__cursorColor @cursorColor.setter def cursorColor(self, cursor_color: QColor) -> None: if self.__cursorColor == cursor_color: return self.__cursorColor = cursor_color self.update() @property def color(self) -> QColor: return self.__color @property def hue(self) -> float: return self.__hue @property def sat(self) -> float: return self.__sat
def openPicture(self, fname): self.setWindowTitle(fname) p = QPixmap(fname) self.label.setPixmap(p) return not p.isNull()