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

2 years ago
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