代码:
# 设置样本图片的QGraphicsView模型
from PySide6.QtCore import Qt, QRectF, QObject
from PySide6.QtGui import QPainter, QPen, QColor, QAction, QMouseEvent
from PySide6.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsPixmapItem, QGraphicsRectItem, QMenu, QWidget, \
QVBoxLayout, QFrame, QSizePolicy
# 矩形方框(QGraphicsRectItem)模型
class MyRectItem(QGraphicsRectItem, QObject):
def __init__(self, *args):
QGraphicsRectItem.__init__(self, *args)
QObject.__init__(self) # 使用父辈的QObject的构造函数,利用它的信号槽机制
self.menu = QMenu() # 创建菜单对象
# 启用鼠标跟踪,以便在没有按下鼠标按钮时也能接收鼠标移动事件
self.setAcceptHoverEvents(True)
self.setMenu() # 设置菜单
def setMenu(self):
"""设置菜单"""
action = QAction("方框菜单", self) # 创建菜单项
self.menu.addAction(action) # 将菜单项添加到菜单中
# def contextMenuEvent(self, event): # 它也可以拥有自己的右键事件响应
# """鼠标右键菜单"""
# self.menu.exec(event.screenPos()) # 在鼠标位置显示菜单
# 设置QGraphicsView模型
class MyView(QGraphicsView):
def __init__(self, parent=None, autoScale=True):
super().__init__(parent)
self.autoScale = autoScale # 自动缩放标志,是否全画幅显示
self.image_item = QGraphicsPixmapItem() # 创建图片对象
self.set_scene() # 设置场景
self.set_menu() # 设置菜单
def set_scene(self):
"""设置场景"""
self.scene = QGraphicsScene() # 创建窗口场景
# 设置渲染提示
self.setRenderHint(QPainter.Antialiasing) # 开启抗锯齿
self.setRenderHint(QPainter.SmoothPixmapTransform) # 开启平滑缩放
# 设置缩放锚点
self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) # 转换时以鼠标为中心
self.setResizeAnchor(QGraphicsView.AnchorUnderMouse) # 缩放时以鼠标为中心
self.setScene(self.scene) # 将场景应用到视窗中
# 处理滚轮事件以实现缩放
def wheelEvent(self, event):
"""处理滚轮事件以实现缩放"""
factor = 1.001 ** event.angleDelta().y() # 滚轮每滚动一格,缩放比例变化
self.scale(factor, factor)
def set_menu(self):
"""设置菜单"""
self.menu = QMenu(self) # 创建菜单对象
action = QAction("视图菜单", self) # 创建菜单项
self.menu.addAction(action) # 将菜单项添加到菜单中
self.image_item.menu = QMenu(self) # 创建菜单对象
action = QAction("图片菜单", self) # 创建菜单项
self.image_item.menu.addAction(action) # 将菜单项添加到菜单中
# 设置图像文件
def set_image(self, pixmap):
self.scene.clear() # 清空场景
self.scene_rect = QRectF(0, 0, pixmap.width(), pixmap.height()) # 设置场景范围
self.image_item.setPixmap(pixmap) # 创建图片对象
self.scene.addItem(self.image_item) # 将图片对象添加到场景中
self.setAlignment(Qt.AlignmentFlag.AlignCenter) # 设置视图对齐方式
if self.autoScale:
self.fitInView(self.image_item, Qt.AspectRatioMode.KeepAspectRatio) # 设置视图适应图片,全幅显示
def contextMenuEvent(self, event):
"""鼠标右键菜单"""
item = self.itemAt(event.pos()) # 获取鼠标位置处的图形项
if item is None: # 如果鼠标位置没有图形项
self.menu.exec(event.globalPos()) # 在鼠标位置显示菜单
else:
try:
item.menu.exec(event.globalPos()) # 在鼠标位置显示菜单
except AttributeError:
pass
if __name__ == "__main__":
import sys
from PySide6.QtWidgets import QApplication
from PySide6.QtGui import QPixmap
app = QApplication(sys.argv)
widget = QWidget() # 创建窗口对象
widget.resize(800, 600) # 设置窗口大小
widget.layout = QVBoxLayout(widget) # 创建垂直布局对象
widget.view = MyView(widget) # 创建MyView对象
widget.layout.addWidget(widget.view) # 将视图添加到布局中
pixmap = QPixmap("flower.jpg") # 创建QPixmap对象
widget.show() # 显示窗口
widget.view.set_image(pixmap) # 设置图像文件
widget.view.scene.addItem(MyRectItem(100,100,100,100)) # 添加矩形框
widget.view.scene.addItem(MyRectItem(300, 300, 100, 100)) # 添加矩形框
sys.exit(app.exec()) # 进入程序的主循环,并通过exit()函数确保主循环安全结束
或者:
import sys
from PySide6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsRectItem, QGraphicsPixmapItem, QMenu
from PySide6.QtGui import QPixmap, QAction
class CustomGraphicsView(QGraphicsView):
def __init__(self):
super().__init__()
scene = QGraphicsScene()
# 添加图片
pixmap = QPixmap("flower.jpg")
pixmap_item = QGraphicsPixmapItem(pixmap)
scene.addItem(pixmap_item)
# 添加两个方框
rect_item1 = QGraphicsRectItem(100, 100, 50, 50)
rect_item2 = QGraphicsRectItem(200, 200, 50, 50)
scene.addItem(rect_item1)
scene.addItem(rect_item2)
self.setScene(scene)
def contextMenuEvent(self, event):
item = self.itemAt(event.pos())
if item:
menu = QMenu(self)
if isinstance(item, QGraphicsPixmapItem):
action = QAction("图片右键菜单选项", self)
menu.addAction(action)
elif isinstance(item, QGraphicsRectItem):
action = QAction("方框右键菜单选项", self)
menu.addAction(action)
menu.exec(event.globalPos())
if __name__ == '__main__':
app = QApplication(sys.argv)
view = CustomGraphicsView()
view.show()
sys.exit(app.exec())