其他分享
首页 > 其他分享> > 实战PyQt5: 085-场景类QGraphicsScene

实战PyQt5: 085-场景类QGraphicsScene

作者:互联网

QGraphicsScene简介

QGraphicsScene是图形视图框架的组成部分。它提供了一个用于管理大量2D图元的表面(Surface)。QGraphicsScene作为QGraphicsItem的容器,与QGraphicsView一起使用,以可视化2D曲面上的图元,例如线条、矩形、文本以及自定义图元。

QGraphicsScene还提供函数来有效确定图元的位置以及确定场景中任意区域内可见的图元。使用QGraphicsView部件,就可以可视化整个场景,或者放大并只查看场景中的某一部分。例如:

scene = QGraphicsScene()
scene.addText('Hello, world')
view = QGraphicsView(scene)
view.show()

注意,QGraphicsScene没有自己的外观显示,它只用于管理图元,需要创建一个QGraphicsView部件来可视化场景。

有两种方法可以将图元添加到场景中,通过调用addItem()将现有的QGraphicsItem对象添加到场景中,或者调用一些便捷函数addEllipse(), addLine(), addPath(), addPixmap(), addPolygon()或者addText()就这些内建图元添加到场景中。使用这些函数添加的图元的尺寸是相对于图元坐标系的,并且图元的位置在场景中被初始化为(0,0)。然后使用QGraphicsView来可视化场景。

QGraphicsScene使用索引算法来管理图元的位置。默认情况下使用BSP(Binary Space Partitioning)树索引算法。

通过调用setSceneRect()设置场景的边界矩形。可以将项目放置在场景中的任何位置,默认情况下,场景的大小不受限制。场景边界矩形仅用于内部标记,维护场景的项目索引。如果未设置场景边界矩形,QGraphicsScene将使用itemsBoundingRect()返回的所有项目的边界区域作为场景边界矩形。但是,itemsBoundingRect()是一个相对耗时的函数,因为它通过收集场景中每个项目的位置信息进行操作。因此,在大型场景上操作时,应始终为场景设置边界矩形。

QGraphicsScene负责传播来自QGraphicsView的事件。

 

QGraphicsScene常用方法:

QGraphicsScene常用信号:

QGraphicsScene类继承关系:

实战PyQt5: 085-场景类QGraphicsScene

 

测试QGraphicsScene

在测试代码中,演示了使用QColorDialog为QGraphicsScene更换背景颜色,以及如何将场景渲染成一个png图像并保存。完整代码如下:

import sys,os,math
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPen, QBrush, QFont,QPainter,QImage,QPainterPath
from PyQt5.QtWidgets import (QApplication, QMainWindow, QGraphicsScene, QGraphicsView,
                             QMenuBar,QMenu,QAction, QColorDialog, QFileDialog,
                             QGraphicsPathItem)
 
class DemoGraphicsScene(QMainWindow):
    def __init__(self, parent=None):
        super(DemoGraphicsScene, self).__init__(parent)   
        
        # 设置窗口标题
        self.setWindowTitle('实战PyQt5: QGraphicsScene Demo!')      
        # 设置窗口大小
        self.resize(480, 360)
      
        self.initUi()
        
    def initUi(self):
        #菜单条
        menuBar = self.menuBar()
        menuFile = menuBar.addMenu('文件')
        
        aSetBkColor = QAction('设置场景背景', self)
        aSetBkColor.triggered.connect(self.onSetBackgroundColor)  
        aExportImage = QAction('导出图像', self)
        aExportImage.triggered.connect(self.onExportImage)
        aExit = QAction('退出', self)
        aExit.triggered.connect(self.close)
        
        menuFile.addAction(aSetBkColor)
        menuFile.addAction(aExportImage)
        menuFile.addSeparator()
        menuFile.addAction(aExit)
        
        #场景部分
        self.scene = QGraphicsScene()
        
        self.scene.addText('Hello Graphics Scene', QFont(self.font().family(), 24))
        
        #添加一个路径(三叶草)
        path = QPainterPath()
        r = 160
        for i in range (3) :
            path.cubicTo(math.cos(2*math.pi*i/3.0)*r, 
                         math.sin(2*math.pi*i/3.0)*r, 
                         math.cos(2*math.pi*(i+0.9)/3.0)*r, 
                         math.sin(2*math.pi*(i+0.9)/3.0)*r, 0, 0)
        pathItem = QGraphicsPathItem()
        pathItem.setPath(path)
        pathItem.setPen(Qt.darkGreen)
        pathItem.setBrush(Qt.darkGreen)
        pathItem.setPos(160, 160)    
        self.scene.addItem(pathItem)
        
        self.view = QGraphicsView()
        self.view.setScene(self.scene)
        
        self.setCentralWidget(self.view)
        
    def onSetBackgroundColor(self):
        dlg = QColorDialog(self)
        dlg.colorSelected.connect(self.onColorSelected)
        dlg.exec()
    
    def onExportImage(self):
        path,_ = QFileDialog.getSaveFileName(self, '保存文件', '', '图像文件 (*.png)')
        if not path:
            return
        
        viewSize = self.view.size()
        width = 320
        height = int(viewSize.height() / viewSize.width() * width)
        image = QImage(width, height, QImage.Format_ARGB32)
        painter = QPainter()
        painter.begin(image)
        painter.setRenderHint(QPainter.Antialiasing) #抗锯齿
        self.scene.render(painter)
        painter.end()
        image.save(path)
 
                
    def onColorSelected(self, color):
        self.scene.setBackgroundBrush(QBrush(color))
    
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = DemoGraphicsScene()
    window.show()
    sys.exit(app.exec()) 

运行效果如下图所示:

实战PyQt5: 085-场景类QGraphicsScene

测试QGraphicsScene

场景输出渲染文件如下图:

实战PyQt5: 085-场景类QGraphicsScene

QGraphicsScene渲图输出图片

本文知识点

前一篇: 实战PyQt5: 084-图形视图框架的关键特性

标签:场景,self,QGraphicsScene,PyQt5,添加,085,图元,math
来源: https://blog.csdn.net/seniorwizard/article/details/110633068