def paint(self, painter, option, index): super(Delegate, self).paint(painter, option, index) # HOVER if option.state & QStyle.State_MouseOver: painter.fillRect(option.rect, QColor("#F1F1F1")) else: painter.fillRect(option.rect, Qt.transparent) # SELECTED if option.state & QStyle.State_Selected: painter.fillRect(option.rect, QColor("#F1F1F1")) # DRAW ICON icon = QPixmap() icon.load(index.data()[1]) icon = icon.scaled(24, 24, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) left = 24 # margin left icon_pos = QRect(left, ((self._height - icon.height()) / 2) + option.rect.y(), icon.width(), icon.height()) painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.SmoothPixmapTransform) painter.drawPixmap(icon_pos, icon) # DRAW TEXT font = QFont("Roboto Black", 12) text_pos = QRect((left * 2) + icon.width(), option.rect.y(), option.rect.width(), option.rect.height()) painter.setFont(font) painter.setPen(Qt.black) painter.drawText(text_pos, Qt.AlignVCenter, index.data()[0])
def paint_with_opacity(pixmap: QPixmap, opacity: float): transparent_image = QImage(QSize(36, 36), QImage.Format_ARGB32_Premultiplied) transparent_image.fill(Qt.transparent) painter = QPainter(transparent_image) painter.setOpacity(opacity) painter.drawPixmap(18 - pixmap.width() / 2, 18 - pixmap.height() / 2, pixmap) painter.end() return QPixmap.fromImage(transparent_image)
def __init__(self): super(MainWindow, self).__init__() self.title = "Image Viewer" self.setWindowTitle(self.title) label = QLabel(self) pixmap = QPixmap('close_16.png') label.setPixmap(pixmap) self.setCentralWidget(label) self.resize(pixmap.width(), pixmap.height())
def fit_to_frame(pixmap: QPixmap, frame: QSize) -> QPixmap: """ :param pixmap: The QPixmap to resize. :param frame: The frame within which the image should fit. :return: A pixmap fitting inside the given frame. """ frame_width, frame_height = frame.toTuple() dw = abs(pixmap.width() - frame_width) dh = abs(pixmap.height() - frame_height) return pixmap.scaledToWidth( frame_width) if dw > dh else pixmap.scaledToHeight(frame_height)
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.transform().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.horizontalAdvance(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())
class BookDelegate(QSqlRelationalDelegate): """Books delegate to rate the books""" def __init__(self, parent=None): QSqlRelationalDelegate.__init__(self, parent) self.star = QPixmap(":/images/star.png") def paint(self, painter, option, index): """ Paint the items in the table. If the item referred to by <index> is a StarRating, we handle the painting ourselves. For the other items, we let the base class handle the painting as usual. In a polished application, we'd use a better check than the column number to find out if we needed to paint the stars, but it works for the purposes of this example. """ if index.column() != 5: # Since we draw the grid ourselves: opt = copy.copy(option) opt.rect = option.rect.adjusted(0, 0, -1, -1) QSqlRelationalDelegate.paint(self, painter, opt, index) else: model = index.model() if option.state & QStyle.State_Enabled: if option.state & QStyle.State_Active: color_group = QPalette.Normal else: color_group = QPalette.Inactive else: color_group = QPalette.Disabled if option.state & QStyle.State_Selected: painter.fillRect( option.rect, option.palette.color(color_group, QPalette.Highlight)) rating = model.data(index, Qt.DisplayRole) width = self.star.width() height = self.star.height() x = option.rect.x() y = option.rect.y() + (option.rect.height() / 2) - (height / 2) for i in range(rating): painter.drawPixmap(x, y, self.star) x += width # Since we draw the grid ourselves: self.drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1)) pen = painter.pen() painter.setPen(option.palette.color(QPalette.Mid)) painter.drawLine(option.rect.bottomLeft(), option.rect.bottomRight()) painter.drawLine(option.rect.topRight(), option.rect.bottomRight()) painter.setPen(pen) def sizeHint(self, option, index): """ Returns the size needed to display the item in a QSize object. """ if index.column() == 5: size_hint = QSize(5 * self.star.width(), self.star.height()) + QSize(1, 1) return size_hint # Since we draw the grid ourselves: return QSqlRelationalDelegate.sizeHint(self, option, index) + QSize( 1, 1) def editorEvent(self, event, model, option, index): if index.column() != 5: return False if event.type() == QEvent.MouseButtonPress: mouse_pos = event.position() new_stars = int(0.7 + (mouse_pos.x() - option.rect.x()) / self.star.width()) stars = max(0, min(new_stars, 5)) model.setData(index, stars) # So that the selection can change return False return True def createEditor(self, parent, option, index): if index.column() != 4: return QSqlRelationalDelegate.createEditor(self, parent, option, index) # For editing the year, return a spinbox with a range from -1000 to 2100. spinbox = QSpinBox(parent) spinbox.setFrame(False) spinbox.setMaximum(2100) spinbox.setMinimum(-1000) return spinbox
class QtImg(QtWidgets.QWidget, Ui_Img): def __init__(self): super(self.__class__, self).__init__() Ui_Img.__init__(self) self.setupUi(self) self.bookId = "" self.epsId = 0 self.curIndex = 0 self.setWindowTitle("IMG") self.setWindowModality(QtCore.Qt.ApplicationModal) self.resize(800, 900) self.checkBox.setChecked(True) self.index = 0 self.comboBox.setCurrentIndex(self.index) validator = QIntValidator(0, 9999999) self.heighEdit.setValidator(validator) self.widthEdit.setValidator(validator) exp = QDoubleValidator(0.1, 64, 1) exp.setNotation(exp.StandardNotation) self.scaleEdit.setValidator(exp) # self.setWindowFlags(Qt.FramelessWindowHint) self.graphicsView.setFrameStyle(QFrame.NoFrame) self.graphicsView.setObjectName("graphicsView") self.graphicsView.setBackgroundBrush(QColor(Qt.white)) self.graphicsView.setCursor(Qt.OpenHandCursor) self.graphicsView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphicsView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphicsView.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) self.graphicsView.setCacheMode(self.graphicsView.CacheBackground) self.graphicsView.setViewportUpdateMode(self.graphicsView.SmartViewportUpdate) self.graphicsItem = QGraphicsPixmapItem() self.graphicsItem.setFlags(QGraphicsPixmapItem.ItemIsFocusable | QGraphicsPixmapItem.ItemIsMovable) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.CopyPicture) self.graphicsScene = QGraphicsScene(self) # 场景 self.graphicsView.setScene(self.graphicsScene) self.graphicsScene.addItem(self.graphicsItem) self.graphicsView.setMinimumSize(10, 10) self.pixMap = QPixmap("Loading") self.graphicsItem.setPixmap(self.pixMap) # self.radioButton.setChecked(True) self.isStripModel = False # self.radioButton.installEventFilter(self) # self.radioButton_2.installEventFilter(self) self.graphicsView.installEventFilter(self) self.graphicsView.setWindowFlag(Qt.FramelessWindowHint) # tta有BUG,暂时屏蔽 TODO # self.ttaModel.setEnabled(False) self.data = b"" self.waifu2xData = b"" self._delta = 0.1 self.scaleCnt = 0 self.backStatus = "" self.format = "" def ShowImg(self, data): if data: self.data = data self.waifu2xData = b"" QtTask().CancelConver("QtImg") self._ShowImg(data) elif self.data: self._ShowImg(self.data) else: pass def _ShowImg(self, data): self.scaleCnt = 0 self.pixMap = QPixmap() self.pixMap.loadFromData(data) self.show() self.graphicsItem.setPixmap(self.pixMap) self.graphicsView.setSceneRect(QRectF(QPointF(0, 0), QPointF(self.pixMap.width(), self.pixMap.height()))) size = ToolUtil.GetDownloadSize(len(data)) self.sizeLabel.setText(size) weight, height = ToolUtil.GetPictureSize(data) self.resolutionLabel.setText(str(weight) + "x" + str(height)) self.ScalePicture() def ScalePicture(self): rect = QRectF(self.graphicsItem.pos(), QSizeF( self.pixMap.size())) unity = self.graphicsView.transform().mapRect(QRectF(0, 0, 1, 1)) width = unity.width() height = unity.height() if width <= 0 or height <= 0: return self.graphicsView.scale(1 / width, 1 / height) viewRect = self.graphicsView.viewport().rect() sceneRect = self.graphicsView.transform().mapRect(rect) if sceneRect.width() <= 0 or sceneRect.height() <= 0: return x_ratio = viewRect.width() / sceneRect.width() y_ratio = viewRect.height() / sceneRect.height() x_ratio = y_ratio = min(x_ratio, y_ratio) self.graphicsView.scale(x_ratio, y_ratio) # if self.readImg.isStripModel: # height2 = self.pixMap.size().height() / 2 # height3 = self.graphicsView.size().height()/2 # height3 = height3/x_ratio # p = self.graphicsItem.pos() # self.graphicsItem.setPos(p.x(), p.y()+height2-height3) self.graphicsView.centerOn(rect.center()) for _ in range(abs(self.scaleCnt)): if self.scaleCnt > 0: self.graphicsView.scale(1.1, 1.1) else: self.graphicsView.scale(1/1.1, 1/1.1) def resizeEvent(self, event) -> None: super(self.__class__, self).resizeEvent(event) self.ScalePicture() def eventFilter(self, obj, ev): if ev.type() == QEvent.KeyPress: return True else: return super(self.__class__, self).eventFilter(obj, ev) def wheelEvent(self, event): if event.angleDelta().y() > 0: self.zoomIn() else: self.zoomOut() def zoomIn(self): """放大""" self.zoom(1.1) def zoomOut(self): """缩小""" self.zoom(1/1.1) def zoom(self, factor): """缩放 :param factor: 缩放的比例因子 """ _factor = self.graphicsView.transform().scale( factor, factor).mapRect(QRectF(0, 0, 1, 1)).width() if _factor < 0.07 or _factor > 100: # 防止过大过小 return if factor >= 1: self.scaleCnt += 1 else: self.scaleCnt -= 1 self.graphicsView.scale(factor, factor) def CopyPicture(self): clipboard = QApplication.clipboard() clipboard.setPixmap(self.pixMap) QtBubbleLabel.ShowMsgEx(self, "Copy Success") return def ReduceScalePic(self): self.zoom(1/1.1) return def AddScalePic(self): self.zoom(1.1) return def OpenPicture(self): try: filename = QFileDialog.getOpenFileName(self, "Open Image", ".", "Image Files(*.jpg *.png)") if filename and len(filename) >= 1: name = filename[0] if os.path.isfile(name): f = open(name, "rb") data = f.read() f.close() self.ShowImg(data) except Exception as ex: Log.Error(ex) return def StartWaifu2xPng(self): if self.StartWaifu2x("png"): self.format = "png" self.changeJpg.setEnabled(False) self.changePng.setEnabled(False) return def StartWaifu2xJPG(self): if self.StartWaifu2x("jpg"): self.format = "jpg" self.changeJpg.setEnabled(False) self.changePng.setEnabled(False) return def StartWaifu2x(self, format): if not self.data: return False if not config.CanWaifu2x: return False from waifu2x_vulkan import waifu2x_vulkan self.SetStatus(False) self.index = self.comboBox.currentIndex() index = self.comboBox.currentIndex() noise = int(self.noiseCombox.currentText()) if index == 0: modelName = "CUNET" elif index == 1: modelName = "PHOTO" elif index == 2: modelName = "ANIME_STYLE_ART_RGB" else: return False if noise == -1: noiseName = "NO_NOISE" else: noiseName = "NOISE"+str(noise) if modelName == "CUNET" and self.scaleRadio.isChecked() and round(float(self.scaleEdit.text()), 1) <= 1: modelInsence = "MODEL_{}_NO_SCALE_{}".format(modelName, noiseName) else: modelInsence = "MODEL_{}_{}".format(modelName, noiseName) if self.ttaModel.isChecked(): modelInsence += "_TTA" model = { "model": getattr(waifu2x_vulkan, modelInsence), } if self.scaleRadio.isChecked(): model['scale'] = round(float(self.scaleEdit.text()), 1) else: model['width'] = int(self.widthEdit.text()) model['high'] = int(self.heighEdit.text()) model['format'] = format self.backStatus = self.GetStatus() QtTask().AddConvertTask(self.data, model, self.AddConvertBack, cleanFlag="QtImg") self.changeLabel.setText(self.tr("正在转换")) return True def AddConvertBack(self, data, waifuId, backParam, tick): if data: self.waifu2xData = data if self.checkBox.isChecked(): self._ShowImg(data) self.changeLabel.setText(self.tr("已转换")) self.tickLabel.setText(str(round(tick, 3)) + "s") else: self.changeLabel.setText(self.tr("失败")) self.SetStatus(True) return def CheckHideButton(self): if self.format == "": self.changePng.setEnabled(True) self.changeJpg.setEnabled(True) elif self.format == "png": self.changePng.setEnabled(False) self.changeJpg.setEnabled(True) else: self.changePng.setEnabled(True) self.changeJpg.setEnabled(False) def SavePicture(self): data = self.waifu2xData if self.waifu2xData else self.data if not data: return try: today = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time())) picFormat = self.format if self.format else "jpg" filepath = QFileDialog.getSaveFileName(self, "Save", "{}.{}".format(today, picFormat)) if filepath and len(filepath) >= 1 and filepath[0]: name = filepath[0] f = open(name, "wb") f.write(data) f.close() except Exception as es: Log.Error(es) return def SwithPicture(self): if self.checkBox.isChecked() and self.waifu2xData: self._ShowImg(self.waifu2xData) else: self._ShowImg(self.data) return def ChangeModel(self, index): # self.index = self.comboBox.currentIndex() self.CheckScaleRadio() return def GetStatus(self): data = str(self.noiseCombox.currentText()) + \ str(self.buttonGroup_2.checkedId()) + \ str(self.scaleEdit.text()) + \ str(self.heighEdit.text()) + \ str(int(self.ttaModel.isChecked())) + \ str(self.widthEdit.text()) + \ str(self.comboBox.currentIndex()) return data def SetStatus(self, status): self.scaleRadio.setEnabled(status) self.heighRadio.setEnabled(status) self.scaleEdit.setEnabled(status) self.widthEdit.setEnabled(status) self.heighEdit.setEnabled(status) self.noiseCombox.setEnabled(status) self.comboBox.setEnabled(status) # self.radioButton_4.setEnabled(status) # self.radioButton_5.setEnabled(status) # self.radioButton_6.setEnabled(status) # self.radioButton_7.setEnabled(status) # self.radioButton_8.setEnabled(status) # self.ttaModel.setEnabled(status) self.CheckScaleRadio() def SetEnable(self): self.SetStatus(True) def SetDisEnable(self): self.SetStatus(False) def CheckScaleRadio(self): if self.scaleRadio.isChecked() and self.scaleRadio.isEnabled(): self.scaleEdit.setEnabled(True) self.widthEdit.setEnabled(False) self.heighEdit.setEnabled(False) elif self.heighRadio.isChecked() and self.heighRadio.isEnabled(): self.scaleEdit.setEnabled(False) self.widthEdit.setEnabled(True) self.heighEdit.setEnabled(True) data = self.GetStatus() if self.backStatus != data: self.changePng.setEnabled(True) self.changeJpg.setEnabled(True) else: self.CheckHideButton()