pyqtgraph
在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的更多相关文章
- Python 图形 GUI 库 pyqtgraph
原文 Python 图形 GUI 库 pyqtgraph pyqtgraph 是纯 Python 图形 GUI 库,基于PyQT4 /pyside和NumPy.它主要目的用于在数学/科学/工程中.M ...
- 【pyqtgraph绘图】案例-动态的正余弦波形图
先看一个简单的小例子: 完整代码: import numpy as np import pyqtgraph as pg import sys from PyQt5.QtWidgets import Q ...
- 【pyqtgraph绘图】线条,填充和颜色
解读官方API-线条,填充和颜色 参考: http://www.pyqtgraph.org/documentation/style.html 线条,填充和颜色 Qt依靠其QColor,QPen和QBr ...
- 【pyqtgraph绘图】在pyqtgraph中绘图
解读pyqtgraph官方API-在pyqtgraph中绘图 参考: http://www.pyqtgraph.org/documentation/plotting.html 在pyqtgraph中绘 ...
- 【pyqtgraph绘图】Qt速成课程
解读官方API-Qt速成课程 参考:http://www.pyqtgraph.org/documentation/qtcrashcourse.html Qt速成课程 PyQtGraph广泛使用Qt来生 ...
- 【pyqtgraph绘图】安装pyqtgraph
解读官方API-安装 安装 参考:http://www.pyqtgraph.org/documentation/installation.html 根据您的需要,有许多不同的方式来安装pyqtgrap ...
- 【pyqtgraph绘图】如何使用pyqtgraph
解读官方API-如何使用pyqtgraph 这里有一些使用pyqtgraph的建议方法: 从交互式shell(python -i,ipython等) 从应用程序显示弹出窗口 在PyQt应用程序中嵌入小 ...
- 【pyqtgraph】pyqtgraph-鼠标互动
pyqtgraph绘图库官方文档学习-鼠标互动(mouse interaction) 鼠标互动 大多数使用pyqtgraph数据可视化的应用程序都会生成可以使用鼠标进行交互式缩放,平移和配置的小部件. ...
- 【PyQt5-Qt Designer】在GUI中使用pyqtgraph绘图库
pyqtgraph绘图库 1.1 简介: pyqtgraph是Python平台上一种功能强大的2D/3D绘图库,相对于matplotlib库,由于内部实现方式上,使用了高速计算的numpy信号处理库以 ...
- python pyqtgraph 保存图片到本地
pyqtgraph官方给的示例居然会报错2333 官方文档传送门:#####pyqtgraph export pyqtgraph支持在可视化窗口中右键保存(Exporting from the GUI ...
随机推荐
- C语言中的类型转换——将字符串s转换为整数型(int)类型
在讲类型转换之前,我们先要理解下C语言中单引号和双引号的区别. 先讲双引号,双引号就是字符串,我们要证实我们的想法,我选择写一段代码看看开: #include <stdio.h> int ...
- 【CF263D】Cycle in Graph
题目大意:给定一个 N 个点,M 条边的无向图,保证图中每个节点的度数大于等于 K,求图中一条长度至少大于 K 的简单路径,输出长度和路径包含的点. 题解:依旧采用记录父节点的方式进行找环,不过需要记 ...
- Python函数--装饰器进阶
开放封闭原则 1.对扩展是开放的 为什么要对扩展开放呢? 我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改.所以我们必须允许代码扩展.添加新功能. 2.对修改是封 ...
- 面试遇到两个稍显变态的题目,mark一下
一. 答案: 二. 这个实际上就是删掉了最大的元素之后,再找一次max,于是就是第二大的元素了. 我也这么想过,但是我基础不好,忘了有max方法,于是就想着两次遍历,但是就不符合题意了 图中的答案甚好 ...
- TODO java疑问
TODOjava 疑惑-关于方法调用的参数是基本类型和引用类型的差别 class DataWrap { int a; int b; } public class ReferenceTransferTe ...
- Luogu P3966 [TJOI2013]单词
题目链接 \(Click\) \(Here\) 本题\(AC\)自动机写法的正解之一是\(Fail\)树上跑\(DP\). \(AC\)自动机是\(Trie\)树和\(Fail\)树共存的结构,前者可 ...
- (最小生成树) codeVs 1231 最优布线问题
题目描述 Description 学校需要将n台计算机连接起来,不同的2台计算机之间的连接费用可能是不同的.为了节省费用,我们考虑采用间接数据传输结束,就是一台计算机可以间接地通过其他计算机实现和另外 ...
- icmpsh解决运行报错
运行./run.sh报错 sysctl -w net.ipv4.icmp_echo_ignore_all=1 >/dev/null python icmpsh_m.py 攻击机ip 目标机ip ...
- 关于web-root和web-inf的用处
web-inf下的页面不能直接反问,必须通过servlet页面进行跳转,安全性高. web-root下的页面能直接通过地址栏来访问,安全性低. 哪些页面放在web-root下,哪些放在web-inf下 ...
- Ipython Notebook ipynb文件转化为Python脚本
欢迎关注博主主页,学习python视频资源 方法1. pycharm可以打开 方法2 https://jingyan.baidu.com/article/19192ad8edc736e53e57072 ...