You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.6 KiB

from PyQt5.QtCore import Qt, QRectF
from PyQt5.QtGui import QCursor, QImage, QPixmap
from PyQt5.QtWidgets import QGraphicsView, QGraphicsPixmapItem, QGraphicsScene, QMenu, QAction, QFileDialog
from cv2 import cvtColor,COLOR_BGR2RGB
class GraphicsView(QGraphicsView):
def __init__(self, parent=None):
super(GraphicsView, self).__init__(parent=parent)
self._zoom = 0
self._empty = True
self._photo = QGraphicsPixmapItem()
self._scene = QGraphicsScene(self)
self._scene.addItem(self._photo)
self.setScene(self._scene)
# self.setScene(self._scene1)
self.setAlignment(Qt.AlignCenter) # 居中显示
self.setDragMode(QGraphicsView.ScrollHandDrag) # 设置拖动
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setMinimumSize(640, 480)
def contextMenuEvent(self, event):
if not self.has_photo():
return
menu = QMenu()
save_action = QAction('另存为', self)
save_action.triggered.connect(self.save_current) # 传递额外值
menu.addAction(save_action)
menu.exec(QCursor.pos())
def save_current(self):
file_name = QFileDialog.getSaveFileName(self, '另存为', './', 'Image files(*.jpg *.gif *.png)')[0]
print(file_name)
if file_name:
self._photo.pixmap().save(file_name)
def get_image(self):
if self.has_photo():
return self._photo.pixmap().toImage()
def has_photo(self):
return not self._empty
def change_image(self, img):
self.update_image(img)
self.fitInView()
def img_to_pixmap(self, img):
img = cvtColor(img, COLOR_BGR2RGB) # bgr -> rgb
h, w, c = img.shape # 获取图片形状
image = QImage(img, w, h, 3 * w, QImage.Format_RGB888)
return QPixmap.fromImage(image)
def update_image(self, img):
self._empty = False
self._photo.setPixmap(self.img_to_pixmap(img))
def fitInView(self, scale=True):
rect = QRectF(self._photo.pixmap().rect())
if not rect.isNull():
self.setSceneRect(rect)
def wheelEvent(self, event):
if self.has_photo():
if event.angleDelta().y() > 0:
factor = 1.25
self._zoom += 1
else:
factor = 0.8
self._zoom -= 1
if self._zoom > 0:
self.scale(factor, factor)
elif self._zoom == 0:
self.fitInView()
else:
self._zoom = 0