在Qt界面库中,对于图形的绘制,在前面介绍了一种使用QPainter实现普通二维图形的绘制方法,该方法在paintEvent事件里编写绘图程序,其本质绘制的图形是位图,这种方法更适合于绘制复杂度不高的固定图形,并且不能实现图项的选择、编辑、拖放、修改等交互功能。

对于需要绘制大量的、需要交互的图形,可使用Graphics View绘图架构,它是一种基于图形项(Graphics Item)的模型/视图模式,这种方式可以在一个场景中可绘制大量图元项,且每个图元项都是可选择、可交互的。

在Graphics View绘图架构中,主要涉及到下面三个类的使用:

1. 场景类(QGraphicsScene):该类提供绘图场景(Scene),场景是不可见的,是一个抽象的管理图形项的容器,可向场景中添加图形项,获取场景中的某个图形项等;

2. 视图类(QGraphicsView):该类提供绘图的视图(View)组件,用于显示场景中的内容。可以为一个场景设置几个视图,用于对同一个数据集提供不同的观察方式;

3. 图形项类(QGraphicsItem):该类提供了一些基本的图形元件,也可在此基础上自定义图形项,它支持各种事件的响应,如鼠标事件、键盘事件、拖放事件等,以实现图形的交互功能

在Graphics View绘图架构中涉及到了3个坐标系,即场景坐标、视图坐标及图形项坐标。其中,场景坐标类似于QPainter的逻辑坐标,一般以场景的中心为原点;视图坐标是窗口界面的物理坐标,其左上角为原点坐标;图形项坐标是局部逻辑坐标,通常以图件的中心为原点

坐标实例

import sys
from PyQt5.QtWidgets import QApplication,QGraphicsScene,QGraphicsView,QGraphicsRectItem,QMainWindow,QLabel,QGraphicsItem,QGraphicsEllipseItem
from PyQt5.QtCore import Qt,pyqtSignal,QPoint,QRectF class QMyGraphicsView(QGraphicsView):
sigMouseMovePoint=pyqtSignal(QPoint)
#自定义信号sigMouseMovePoint,当鼠标移动时,在mouseMoveEvent事件中,将当前的鼠标位置发送出去
#QPoint--传递的是view坐标
def __init__(self,parent=None):
super(QMyGraphicsView,self).__init__(parent) def mouseMoveEvent(self, evt):
pt=evt.pos() #获取鼠标坐标--view坐标
self.sigMouseMovePoint.emit(pt) #发送鼠标位置
QGraphicsView.mouseMoveEvent(self, evt) class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.resize(600,400)
self.view=QMyGraphicsView() #创建视图窗口
self.setCentralWidget(self.view) # 设置中央控件
self.statusbar=self.statusBar() #添加状态栏
self.labviewcorrd=QLabel('view坐标:')
self.labviewcorrd.setMinimumWidth(150)
self.statusbar.addWidget(self.labviewcorrd)
self.labscenecorrd=QLabel('scene坐标:')
self.labscenecorrd.setMinimumWidth(150)
self.statusbar.addWidget(self.labscenecorrd)
self.labitemcorrd = QLabel('item坐标:')
self.labitemcorrd.setMinimumWidth(150)
self.statusbar.addWidget(self.labitemcorrd)
rect=QRectF(-200,-100,400,200)
self.scene=QGraphicsScene(rect) #创建场景
#参数:场景区域
#场景坐标原点默认在场景中心---场景中心位于界面中心
self.view.setScene(self.scene) #给视图窗口设置场景
item1=QGraphicsRectItem(rect) #创建矩形---以场景为坐标
item1.setFlags(QGraphicsItem.ItemIsSelectable|QGraphicsItem.ItemIsFocusable|QGraphicsItem.ItemIsMovable) #给图元设置标志
#QGraphicsItem.ItemIsSelectable---可选择
#QGraphicsItem.ItemIsFocusable---可设置焦点
#QGraphicsItem.ItemIsMovable---可移动
#QGraphicsItem.ItemIsPanel---
self.scene.addItem(item1) #给场景添加图元
for pos,color in zip([rect.left(),0,rect.right()],[Qt.red,Qt.yellow,Qt.blue]):
item=QGraphicsEllipseItem(-50,-50,100,100) #创建椭圆--场景坐标
#参数1 参数2 矩形左上角坐标
#参数3 参数4 矩形的宽和高
item.setPos(pos,0) #给图元设置在场景中的坐标(移动图元)--图元中心坐标
item.setBrush(color) #设置画刷
item.setFlags(QGraphicsItem.ItemIsSelectable|QGraphicsItem.ItemIsFocusable|QGraphicsItem.ItemIsMovable)
self.scene.addItem(item)
self.scene.clearSelection() #【清除选择】
self.view.sigMouseMovePoint.connect(self.slotMouseMovePoint) def slotMouseMovePoint(self,pt):
self.labviewcorrd.setText('view坐标:{},{}'.format(pt.x(),pt.y()))
ptscene=self.view.mapToScene(pt) #把view坐标转换为场景坐标
self.labscenecorrd.setText('scene坐标:{:.0f},{:.0f}'.format(ptscene.x(),ptscene.y()))
item=self.scene.itemAt(ptscene,self.view.transform()) #在场景某点寻找图元--最上面的图元
#返回值:图元地址
#参数1 场景点坐标
#参数2 ????
if item != None:
ptitem=item.mapFromScene(ptscene) #把场景坐标转换为图元坐标
self.labitemcorrd.setText('item坐标:{:.0f},{:.0f}'.format(ptitem.x(),ptitem.y())) if __name__ == "__main__":
app = QApplication(sys.argv)
ex = MainWindow()
ex.show()
sys.exit(app.exec_())

import sys
from PyQt5.QtWidgets import QWidget, QApplication,QGraphicsScene,QGraphicsView
import time class Example(QWidget):
def __init__(self):
super().__init__()
self.resize(500,400)
scene=QGraphicsScene(self) #创建场景
self.t=scene.addText("Hello, world!") #在场景中添加文本
view=QGraphicsView(scene,self) #创建视图窗口
view.move(10,10)
view.show() #显示 if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
 

添加文本图元

font=QFont("华文琥珀",20,QFont.Bold)
t=scene.addText("Hello, world!",font) #在场景中添加文本图元
#参数1 文本
#参数2 字体

添加矩形

pen = QPen()
pen.setColor(Qt.blue)
pen.setWidth(3)
brush = QBrush(Qt.SolidPattern)
brush.setColor(Qt.yellow)
rect = QRectF(130,130,100,150)
juxin=scene.addRect(30,30,100,100,pen,brush) #添加矩形图元--方式一
#参数1--参数4 坐标和宽高---以View为坐标系
#参数5 画笔
#参数6 画刷
juxin = scene.addRect(rect, pen, brush) # 添加矩形图元--方式二
rect = QRectF(0,0,100,100)
item1 = QGraphicsRectItem(rect) # 创建矩形---以场景为坐标
scene.addItem(item1)

添加线段

pen = QPen()
pen.setColor(Qt.blue)
pen.setWidth(3)
line=scene.addLine(0,0,50,50,pen) #添加直线--方式一
lf=QLineF(50,50,0,50)
line = scene.addLine(lf, pen) #添加直线--方式二

添加椭圆

item = QGraphicsEllipseItem(10, 10, 100, 100)  # 创建椭圆--场景坐标
# 参数1 参数2 矩形左上角坐标
# 参数3 参数4 矩形的宽和高
scene.addItem(item)
item=scene.addEllipse(10, 10, 100, 100,pen,brush)
rect=QRectF(10, 10, 100, 100)
item=scene.addEllipse(rect,pen,brush)

图元的操作(缩放,平移,旋转)

想要旋转,平移,缩放窗口中的图元,一般有两种思路:

1. 操作View,概念类似于旋转摄像头,从而获取对场景Scene的不同观察结果,这样操作的好处是,场景中的图元本质上没有发生任何的变化,仅仅改变了View的计算矩阵,效率非常高,并且,如果该Scene被多个View绑定观察,对单独一个view的操作,将不会影响到别的view的观察结果

2.操作Scene中所有的图元Item或者直接操作单个图元Item,概念类似于真实改变了场景中的各个物体的摆放方式,该方法使用的场合位:当一个场景,被多个view观察的时候,场景中的某一个变化操作,需要被这多个view同时观察到

下面是操作图元的方法

1. 图元的缩放:

rect=QRectF(100, 100, 200, 100)
item=scene.addEllipse(rect,pen,brush)
item.setScale(0.5) #对图元进行缩放
#参数为图元大小的缩放比
#需要注意的是,该方法的缩放基准是固定的,也就是说,如果连续两次调用该方法,但是参数的数字一样的话,第二次的调用将不会改变图元的大小
print(item.scale()) #返回图元的缩放比

2.图元的平移

item=scene.addRect(200,200,200,100,pen,brush)
item.setPos(100,50) #移动图元--方式一
#参数 移动的偏移量
#其传参的x与y坐标值,属于场景Scene的坐标,如果调用的时候,坐标来源于view的鼠标点击事件的坐标,需要调用mapToScene()将view坐标值转换到场景坐标
item.moveBy(100,50) #移动图元--方式二

3.图元的旋转

import sys
from PyQt5.QtWidgets import QWidget, QApplication,QGraphicsScene,QGraphicsView,QGraphicsRectItem,QGraphicsEllipseItem,QGraphicsItem,QPushButton
from PyQt5.QtGui import QPen,QBrush
from PyQt5.QtCore import Qt,QRectF,QLineF class Example(QWidget):
def __init__(self):
super().__init__()
self.resize(500,400)
scene=QGraphicsScene() #创建场景 scene.setSceneRect(0,0,600,500) #设置场景的坐标原点和宽高
pen = QPen()
pen.setColor(Qt.blue)
pen.setWidth(3)
brush=QBrush(Qt.yellow) item1=scene.addRect(0,0,250,25,pen,brush) item=scene.addRect(100,100,200,100,pen,brush)
item.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsFocusable | QGraphicsItem.ItemIsMovable)
item.setPos(-100, -100)
item.setTransformOriginPoint(0,0) #设置旋转中心----???不按这点旋转啊
#默认 图元的左上角
#该方法传参的坐标值为图元自身的坐标系
item.setRotation(30) #旋转图元
#参数 角度
#正数 逆时针
#设置的值的基准也是不变的,也就是说,连续两次调用该方法,都传入相同的参数值,图元只会旋转一次
print(item.rotation()) #返回旋转角度 view=QGraphicsView(scene,self) #创建视图窗口
view.resize(500,400)
view.show() #显示 if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

天子骄龙

item=QGraphicsEllipseItem(-,-,,)  #创建椭圆--场景坐标
#参数1 参数2 矩形左上角坐标
#参数3 参数4 矩形的宽和高

pyqtgraph的更多相关文章

  1. Python 图形 GUI 库 pyqtgraph

    原文  Python 图形 GUI 库 pyqtgraph pyqtgraph 是纯 Python 图形 GUI 库,基于PyQT4 /pyside和NumPy.它主要目的用于在数学/科学/工程中.M ...

  2. 【pyqtgraph绘图】案例-动态的正余弦波形图

    先看一个简单的小例子: 完整代码: import numpy as np import pyqtgraph as pg import sys from PyQt5.QtWidgets import Q ...

  3. 【pyqtgraph绘图】线条,填充和颜色

    解读官方API-线条,填充和颜色 参考: http://www.pyqtgraph.org/documentation/style.html 线条,填充和颜色 Qt依靠其QColor,QPen和QBr ...

  4. 【pyqtgraph绘图】在pyqtgraph中绘图

    解读pyqtgraph官方API-在pyqtgraph中绘图 参考: http://www.pyqtgraph.org/documentation/plotting.html 在pyqtgraph中绘 ...

  5. 【pyqtgraph绘图】Qt速成课程

    解读官方API-Qt速成课程 参考:http://www.pyqtgraph.org/documentation/qtcrashcourse.html Qt速成课程 PyQtGraph广泛使用Qt来生 ...

  6. 【pyqtgraph绘图】安装pyqtgraph

    解读官方API-安装 安装 参考:http://www.pyqtgraph.org/documentation/installation.html 根据您的需要,有许多不同的方式来安装pyqtgrap ...

  7. 【pyqtgraph绘图】如何使用pyqtgraph

    解读官方API-如何使用pyqtgraph 这里有一些使用pyqtgraph的建议方法: 从交互式shell(python -i,ipython等) 从应用程序显示弹出窗口 在PyQt应用程序中嵌入小 ...

  8. 【pyqtgraph】pyqtgraph-鼠标互动

    pyqtgraph绘图库官方文档学习-鼠标互动(mouse interaction) 鼠标互动 大多数使用pyqtgraph数据可视化的应用程序都会生成可以使用鼠标进行交互式缩放,平移和配置的小部件. ...

  9. 【PyQt5-Qt Designer】在GUI中使用pyqtgraph绘图库

    pyqtgraph绘图库 1.1 简介: pyqtgraph是Python平台上一种功能强大的2D/3D绘图库,相对于matplotlib库,由于内部实现方式上,使用了高速计算的numpy信号处理库以 ...

  10. python pyqtgraph 保存图片到本地

    pyqtgraph官方给的示例居然会报错2333 官方文档传送门:#####pyqtgraph export pyqtgraph支持在可视化窗口中右键保存(Exporting from the GUI ...

随机推荐

  1. A1141. PAT Ranking of Institutions

    After each PAT, the PAT Center will announce the ranking of institutions based on their students' pe ...

  2. A1109. Group Photo

    Formation is very important when taking a group photo. Given the rules of forming K rows with N peop ...

  3. 【洛谷P4318】完全平方数

    题目大意:求第 K 个无平方因子数. 题解:第 k 小/大的问题一般采用二分的方式,通过判定从 1 到当前数中满足某一条件的数有多少个来进行对上下边界的转移. 考虑莫比乌斯函数的定义,根据函数值将整数 ...

  4. 【洛谷P2966】Cow Toll Paths

    题目大意:给定 N 个节点,M 条边的无向图,边有边权,点有点权,现给出 Q 个询问,每个询问查询两个节点之间的最短路径,这里最短路径的定义是两个节点之间的最短路径与这条路径中经过的节点点权的最大值之 ...

  5. JavaScript深入之变量对象

    前言 在上篇<javascript深入之执行上下文栈>中讲到,当javascript代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution ...

  6. bzoj2553 禁忌

    题目链接 题意 给出一个\(n\)个字符串的字典.对于一个字符串,他的贡献是这个字符串中最多的在字典中出现的不重叠子串的数量. 然后问一个长度为\(len\)的,字符集为前\(alphabet\)个字 ...

  7. js 判断所选时间(或者当前时间)是否在某一时间段的实现代码

    var time_range = function (beginTime, endTime, nowTime) { var strb = beginTime.split (":") ...

  8. win32-api: 让 static 控件中的水平横行,垂直居中。

    CreateWindowEx(....., SS_CENTER | SS_CENTERIMAGE); SS_CENTER  能让文字水平居中. SS_CENTERIMAGE 能让文字垂直居中. htt ...

  9. bouncing-balls

    效果如下: 代码目录如下: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charse ...

  10. ERRORS: ?: (staticfiles.E002) The STATICFILES_DIRS setting should not contain the STATIC_ROOT setting.

    Ubuntu下,运行django项目的时候失败,报错: (env36) root@JD:~/xueyiwang# python manage.py runserver 0.0.0.0:8000 Per ...