一、概述

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 #接管图形场景的鼠标事件

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)

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")

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

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

4.7、运行效果

广告

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

》。如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

跟老猿学Python、学5G!

第15.47节、PyQt显示部件:QGraphicsView图形视图和QGraphicsScene图形场景简介及应用案例的更多相关文章

  1. 第四十章、PyQt显示部件:QGraphicsView图形视图和QGraphicsScene图形场景简介及应用案例

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 Designer中的Graphics V ...

  2. 第15.38节 PyQt(Python+Qt)入门学习:containers容器类部件QDockWidget停靠窗功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QDockWidget类提供了一个可以停靠在QMainWin ...

  3. 第15.37节 PyQt(Python+Qt)入门学习:containers容器类部件QMdiArea多文档界面部件详解及编程开发案例

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 老猿在前期学习PyQt相关知识时,对每个组件的属性及方法都研 ...

  4. 第15.30节 PyQt编程实战:通过eventFilter监视QScrollArea的widget()的Paint消息画出scrollAreaWidgetContents的范围矩形

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 在<PyQt(Python+Qt)学习随笔:QScrollArea滚动区域详解> ...

  5. 第15.25节 PyQt(Python+Qt)入门学习:Model/View开发实战--使用QTableView展示Excel文件内容

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 在前面的订阅专栏<第十九章.Model/View开发:QTableView的功能及属 ...

  6. 第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

    老猿Python博文目录 老猿Python博客地址 一.概述 在PyQt图形界面中,支持采用Model/View架构实现数据和界面逻辑分离,其中Model用于处理数据存储,View用于界面数据展现,当 ...

  7. 第15.9节 PyQt学习入门:使用Qt Designer进行GUI设计的步骤

    在使用Qt Designer进行GUI设计时,一般常规的步骤都是差不多的,主要步骤包括新建显示窗口.在窗口上按照规划的布局放置组件.设置初始化组件的属性.定义信号和槽函数的连接,一般后三步是每增加一个 ...

  8. 第15.7节 PyQt入门学习:PyQt5应用构建详细过程介绍

    一. 引言 在上节<第15.6节 PyQt5安装与配置>结束了PyQt5的安装和配置过程,本节将编写一个简单的PyQt5应用,介绍基本的PyQt5应用的文件组成及相关工具的使用. 本节的应 ...

  9. 第15.17节 PyQt(Python+Qt)入门学习:PyQt图形界面应用程序的事件捕获方法大全及对比分析

    老猿Python博文目录 老猿Python博客地址 按照老猿规划的章节安排,信号和槽之后应该介绍事件,但事件在前面的随笔<PyQt(Python+Qt)实现的GUI图形界面应用程序的事件捕获方法 ...

随机推荐

  1. 【Kata Daily 190919】Sort Out The Men From Boys(排序)

    题目: Scenario Now that the competition gets tough it will Sort out the men from the boys . Men are th ...

  2. 从直播商城系统的KOL效应分析,直播带货井喷的必然性

    网红营销.直播带货作为近年来的热点发展迅猛,同时也捧红了一个概念:KOL.随着直播商城系统的不断完善发展,让KOL成为近年来营销最热门的香饽饽.随着原创直播平台低门槛化.模板化内容创作和大数据智能分发 ...

  3. 3、编程语言与Python介绍

    一 引子 基于上一章所学,有了计算机硬件,再在硬件之上安装好操作系统,我们就有了一个应用程序的运行平台,我们接下来的任务就是学习如何使用某款编程语言来开发应用程序. 本章的主题是先了解一下编程语言,然 ...

  4. Spark Standalone模式 高可用部署

      本文使用Spark的版本为:spark-2.4.0-bin-hadoop2.7.tgz. spark的集群采用3台机器进行搭建,机器分别是server01,server02,server03. 其 ...

  5. 打包项目成war包并部署到服务器上,项目运行一直显示加载中

    查看服务器上的Tomcat路径下的log 显示 org.apache.catalina.LifecycleException: Failed to initialize component [Conn ...

  6. string.contains()

    public class test { public static void main(String[] args){ System.out.println("abcde".con ...

  7. TCP中RTT的测量和RTO的计算

    https://blog.csdn.net/zhangskd/article/details/7196707 tcp传输往返时间是指:发送方发送tcp断开时, 到发送方接收到改段立即响应的所耗费的时间 ...

  8. orphan sockets

    orphan sockets 介绍一下什么是 orphan sockets,简单来说就是该 socket 不与任何一个文件描述符相关联.例如,当应用调用 close() 关闭一个链接时,此时该 soc ...

  9. MVCC(转)

    什么是 MVCC MVCC (Multiversion Concurrency Control) 中文全程叫多版本并发控制,是现代数据库(包括 MySQL.Oracle.PostgreSQL 等)引擎 ...

  10. python 《numpy》

    import numpy as np 创建一个矩阵 array = np.array([[1, 2, 3], [3, 2, 1]]) print(array) # [[1 2 3] # [3 2 1] ...