文章目录
- 源码
- untitled.py
- main.py
- 缩放
图形界面使用Qt Designer绘制,如下
菜单项添加一个open选项,窗口上是一个graphicsView组件。
主要流程
- 使用opencv 打开图片
- cv2转为QImage
- QImage转为QPixmap
- 把QPixmap加入到QGraphicsScene
- 把QGraphicsScene加入到graphicsView
- graphicsView show
源码
untitled.py
# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'untitled.ui'## Created by: PyQt5 UI code generator 5.15.4## WARNING: Any manual changes made to this file will be lost when pyuic5 is# run again. Do not edit this file unless you know what you are doing.from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(800, 600) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName("verticalLayout") self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget) self.graphicsView.setObjectName("graphicsView") self.verticalLayout.addWidget(self.graphicsView) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23)) self.menubar.setObjectName("menubar") self.menuopen = QtWidgets.QMenu(self.menubar) self.menuopen.setObjectName("menuopen") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.actionopen = QtWidgets.QAction(MainWindow) self.actionopen.setObjectName("actionopen") self.menuopen.addAction(self.actionopen) self.menubar.addAction(self.menuopen.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.menuopen.setTitle(_translate("MainWindow", "File")) self.actionopen.setText(_translate("MainWindow", "open"))
main.py
#!-*- coding:utf-8 -*-import sys, cv2from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QGraphicsScenefrom PyQt5.QtGui import QPixmap, QImageimport untitledclass mainWindow(QMainWindow): def __init__(self): super(mainWindow, self).__init__() self.ui = untitled.Ui_MainWindow() self.ui.setupUi(self) # 定义菜单open打开图片 self.ui.actionopen.triggered.connect(self.open2show) # 使用graphicsView显示图片 self.scene = QGraphicsScene() # 创建画布 self.ui.graphicsView.setScene(self.scene) # 把画布添加到窗口 self.ui.graphicsView.show() def open2show(self): print("open triggered") qfile = QFileDialog.getOpenFileName(None, "open image file", ".", "Image files (*.bmp *.jpg *.png)") img = cv2.imread(qfile[0]) cvimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 把opencv 默认BGR转为通用的RGB y, x = img.shape[:-1] frame = QImage(cvimg, x, y, QImage.Format_RGB888) self.scene.clear() #先清空上次的残留 self.pix = QPixmap.fromImage(frame) self.scene.addPixmap(self.pix)if __name__ == '__main__': app = QApplication(sys.argv) main = mainWindow() main.show() sys.exit(app.exec_())
缩放
网上有大神直接重新graphicsView类实现图片拖拽与缩放,很少看到用Qt Designer绘制UI并实现缩放的,这里提供一个Qt Designer绘制UI的缩放示例以供参考。
注意:
- 需要重写wheelEvent 滚轮事件函数,实现graphicsView 缩放功能
- 使用Qt Designer绘制时,不填graphicsView组件,需在代码中添加
下面直接上代码
untitled.py 窗口UI代码,使用Qt Designer编写生成
# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'untitled.ui'## Created by: PyQt5 UI code generator 5.15.4## WARNING: Any manual changes made to this file will be lost when pyuic5 is# run again. Do not edit this file unless you know what you are doing.from PyQt5 import QtCore, QtWidgetsclass Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(800, 600) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) self.verticalLayout.setObjectName("verticalLayout") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23)) self.menubar.setObjectName("menubar") self.menuFile = QtWidgets.QMenu(self.menubar) self.menuFile.setObjectName("menuFile") MainWindow.setMenuBar(self.menubar) self.actionopen = QtWidgets.QAction(MainWindow) self.actionopen.setObjectName("actionopen") self.menuFile.addAction(self.actionopen) self.menubar.addAction(self.menuFile.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.menuFile.setTitle(_translate("MainWindow", "File")) self.actionopen.setText(_translate("MainWindow", "open"))
newGraphicsView.py 重写QGraphicsView类
from PyQt5.QtCore import Qtfrom PyQt5.QtGui import QWheelEventfrom PyQt5.QtWidgets import QGraphicsViewclass GraphicsView(QGraphicsView): def __init__(self, parent=None): super().__init__(parent=parent) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setTransformationAnchor(self.AnchorUnderMouse) def wheelEvent(self, e: QWheelEvent): self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) if e.angleDelta().y() > 0: self.scale(1.1, 1.1) else: self.scale(1 / 1.1, 1 / 1.1) self.setTransformationAnchor(self.AnchorUnderMouse)
main.py
#!-*- coding: utf-8 -*-import sys, cv2from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QGraphicsScene, QGraphicsPixmapItem, QGraphicsItemfrom PyQt5.QtGui import QPixmap, QImagefrom PyQt5.QtCore import Qtimport untitledfrom newGraphicsView import GraphicsViewclass MyMainWindow(QMainWindow): def __init__(self): super(MyMainWindow, self).__init__() self.ui = untitled.Ui_MainWindow() self.ui.setupUi(self) self.ui.actionopen.triggered.connect(self.showImage) # self.graphicsView = GraphicsView() self.ui.verticalLayout.addWidget(self.graphicsView) self.scene = QGraphicsScene() # 创建画布 self.graphicsView.setScene(self.scene) # 把画布添加到窗口 self.graphicsView.show() def showImage(self): qFile = QFileDialog.getOpenFileName(self, "Page Designer - Add Pixmap", "", "Pixmap Files (*.bmp *.jpg *.png *.xpm)") print(qFile) if not qFile[0]: print("no image select, to return") return img = cv2.imread(qFile[0]) cvimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 把opencv 默认BGR转为通用的RGB y, x = img.shape[:-1] frame = QImage(cvimg, x, y, QImage.Format_RGB888) # 清除scene残留 self.scene.clear() self.pix = QPixmap.fromImage(frame) item = QGraphicsPixmapItem(QPixmap(frame)) item.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable) self.scene.addItem(item) # # 平滑缩放,平滑后看不到像素点块 # item.setTransformationMode(Qt.SmoothTransformation) # 让image填充显示窗口 self.graphicsView.fitInView(item, Qt.KeepAspectRatio) passif __name__ == '__main__': app = QApplication(sys.argv) main = MyMainWindow() main.show() sys.exit(app.exec_())
以下是QGraphicsView系统框图,标识系统内各组件关系