首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

第15.47节、PyQt显示部件:QGraphicsView图形视图和QGraphicsScene图形场景简介及应用案例

  • 23-09-22 13:02
  • 2036
  • 11682
blog.csdn.net
  • 专栏:Python基础教程目录
  • 专栏:使用PyQt开发图形界面Python应用
  • 专栏:PyQt入门学习
  • 老猿Python博文目录
  • 老猿学5G博文目录

一、概述

Designer中的Graphics View部件是个图形视图部件,对应类为QGraphicsView,其功能不是简单的显示图形,老猿认为这是一种特殊的视图,它与QGraphicsScene配套实现了类似Model/View的架构。

本节不介绍QGraphicsView和QGraphicsScene的所有属性、方法,大家可以参考官方文档,另外老猿推荐《Qt绘图之QGraphicsScene QGraphicsView QGraphicsItem详解》供大家参考。

二、QGraphicsView功能简介

QGraphicsView主要是用于界面显示图形的,显示的内容由QGraphicsScene决定。QGraphicsView支持鼠标的拖拽、点击、滚动等事件,可以根据滚动条策略控制滚动条的出现,提供视图、场景的坐标映射,支持设置对齐方式。

具体属性、方法、信号可以参考官方文档以及上面推荐的博文,在此需要重点说明如下几点:

  1. QGraphicsView默认是带有内边距和边界,会导致内置于内的QGraphicsScene坐标与视图看到的效果不一致,具体请参考《QT:QGraphicsView QGraphicsScene QGraphicsItem理解》
  2. QGraphicsView的坐标体系与QWidget的坐标体系相同,视口范围需要从其viewport视口属性获取
  3. QGraphicsView的场景可以从scene()方法获取,场景大小范围可以从sceneRect()获取
  4. QGraphicsView的默认是居中对齐的,所以如果添加显示对象,默认是显示在中央的

三、QGraphicsScene功能简介

QGraphicsScene用于管理一个需要绘制的图形对象,每个对象称为图元(基类为QGraphicsItem),如果理解QGraphicsScene为一个Model对象的话,QGraphicsItem就是Model中的项。

QGraphicsItem具体属性、方法、信号可以参考官方文档以及上面推荐的博文,在此需要重点说明如下几点:

  1. QGraphicsScene的图元类型有多种,每种图元在添加时要调用专属的添加方法,方法会返回对应的图元类型对象。这些方法包括addLine()、addPath()、addPixmap()、 addRect()、 addText()、addEllipse()、addPolygon()、addSimpleText等
  2. QGraphicsScene的图元都可以通过setPos方法改变其位置,但需要注意,QGraphicsScene的坐标体系与QGraphicsView不同,具体请参考前面推荐的博文
  3. QGraphicsScene提供了大多数的鼠标和键盘等事件处理虚方法,如mousePressEvent、mouseMoveEvent、mouseReleaseEvent、mouseDoubleClickEvent、keyReleaseEvent、keyPressEvent等,可以通过子类化或者动态赋值方式接管相关的事件处理,从而实现对应的处理。但需要注意的是,这些方法中鼠标的位置应该通过scenePos()来获取,不能通过pos()来获取,pos是仅当鼠标点击了对应图元的时候才有值

四、案例

4.1、案例功能说明

在案例中需要在界面上显示如下内容:
在这里插入图片描述
并实现除HELLO外的部分随鼠标点击移动位置。上面的内容包括图片、文字、直线、椭圆以及曲线。

4.2、界面设计

界面UI设计非常简单,就是一个窗口中放置了一个QGraphicsView,如图:
在这里插入图片描述
窗口命名为mainWin,图形视图命名为graphicsView。

4.3、实现界面派生类构造方法

构造方法中除了图形界面初始化外,还将图形视图的内边距和边界去除、改变图形视图的对齐方式、设置场景大小和图形视图大小一致,并绘制图形,同时接管图形场景的mousePressEvent 方法。具体代码如下:

class mainWin(QtWidgets.QWidget,ui_mainWin.Ui_mainWin):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.graphicsView.setStyleSheet("padding: 0px; border: 0px;")#内边距和边界去除
        self.scene = QtWidgets.QGraphicsScene(self)
        self.graphicsView.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) #改变对齐方式

        self.graphicsView.setSceneRect(0,0,self.graphicsView.viewport().width(),self.graphicsView.height()) #设置图形场景大小和图形视图大小一致
        self.graphicsView.setScene(self.scene)
        self.addScenes() #调用绘制图形的方法
        self.scene.mousePressEvent = self.mousePressEvent  #接管图形场景的鼠标事件
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

4.4、实现绘制图形的addScenes方法

    def addScenes(self): #绘制图形
        originX,originY = 40,60  #坐标基点
        self.itemHELLO = self.scene.addText("HELLO!")  #输出hello
        self.itemHELLO.setPos(0, 0)

        #绘制矩形
        pen = QtGui.QPen(QtGui.QColor(QtCore.Qt.red))
        rectF = QtCore.QRectF(originX+300-8, originY-25, 20, 50)
        self.elpItem = self.scene.addEllipse(rectF, pen)

        # 绘制曲线
        pen.setColor(QtGui.QColor(QtCore.Qt.blue))
        path = QtGui.QPainterPath()
        path.moveTo(originX,originY)
        path.cubicTo(originX+100, originY-150, originX+200, originY+150,originX+300,originY)
        myGradient = QtGui.QLinearGradient()
        myFont = QtGui.QFont()
        textPoint = QtCore.QPointF(originX+35,originY-4)
        path.addText(textPoint, myFont, "老猿Python")
        self.itemPath = self.scene.addPath(path,pen,myGradient)
        #绘制下划线
        pen.setColor(QtGui.QColor(QtCore.Qt.darkRed))
        line = QtCore.QLineF(QtCore.QPointF(originX+190, originY-20), QtCore.QPointF(originX+275, originY-20))
        self.itemLine = self.scene.addLine(line, pen)
        self.itemLine.setPos(0,originY-20)

        #绘制文字
        self.itemText = self.scene.addText("跟老猿学Python!")
        self.itemText.setPos(originX+185,originY+1)
        
        #绘制图片
        pixmap = QtGui.QPixmap(r"F:coffeDog咖啡狗小图.jpg")
        self.pixmapItem = self.scene.addPixmap(pixmap)
        self.pixmapItem.setPos(originX-34,originY-16)
        
        #绘制x轴
        pen.setColor(QtGui.QColor(QtCore.Qt.red))
        self.xLine = self.scene.addLine(originX,originY, originX+300, originY, pen)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

4.5、实现鼠标按键响应myMousePressEvent方法

注意这个方法不要命名为mousePressEvent,因为这样不但会接管图形场景的鼠标按键事件,而且会接管主窗口的鼠标按键事件,而二者的参数类型是不同的,对应属性也不同。

    def myMousePressEvent(self,mouseEvent):
        print("myMousePressEvent",mouseEvent.type(),mouseEvent.scenePos())
        point = mouseEvent.scenePos()
        if  point:
            self.movePath(point) #移动相关图元,方法单独实现
        else:print("not valid point")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

4.6、实现图元移动的movePath方法

在该方法中需要将相关图元的位置同步移动,所以在绘制方法中记录下来了所有图元对象。移动图元是参考图片的坐标。

4.7、运行效果

在这里插入图片描述

广告

老猿关于PyQt的付费专栏《使用PyQt开发图形界面Python应用》只需要9.9元,该部分与第十五章的内容基本对应,但同样内容在付费专栏上总体来说更详细、案例更多。本节内容对应付费专栏的《第四十章、PyQt显示部件:QGraphicsView图形视图和QGraphicsScene图形场景简介及应用案例
》。如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

跟老猿学Python、学5G!

  • 专栏:Python基础教程目录
  • 专栏:使用PyQt开发图形界面Python应用
  • 专栏:PyQt入门学习
  • 老猿Python博文目录
  • 老猿学5G博文目录
文章知识点与官方知识档案匹配,可进一步学习相关知识
Python入门技能树首页概览333550 人正在系统学习中
老猿Python
微信公众号
专注Python相关语言、图像音视频处理、AI
注:本文转载自blog.csdn.net的LaoYuanPython的文章"https://blog.csdn.net/LaoYuanPython/article/details/105822587"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top