实战PyQt5: 085-场景类QGraphicsScene

实战PyQt5: 085-场景类QGraphicsSceneQGraphicsScene简介QGraphicsScene是图形视图框架的组成部分。它提供了一个用于管理大量2D图元的表面(Surface)。QGraphicsScene作为QGraphicsItem的容器,与QGraphicsView一起使用,以可视化2D曲面上的图元,例如线条、矩形、文本以及自定义图元。QGraphicsScene还提供函数来有效确定图元的位置以及确定场景中任意区域内可见的图元。使用QGraphicsView部件,就可以可视化整个场景,或者放大并只查看场景中的某一部分。例如:

大家好,欢迎来到IT知识分享网。

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常用方法:

  • addItem(): 添加指定图元及其子图元到场景中;
  • addEllipse(): 创建一个椭圆形图元并添加到场景中;
  • addLine(): 创建一个线图元并添加到场景中;
  • addPath(): 创建一个路径图元并将其添加到场景中;
  • addPixmap(): 创建一个pixmap图元并将其添加到场景中;
  • addPolygon(): 创建一个多边形图元并将其添加到场景中;
  • addRect(): 创建一个矩形图元并将其添加到场景中;
  • addSimpleText(): 创建一个QGraphicsSimpleTextItem并将其添加到场景;
  • addText(): 创建一个文本图元并将其添加到场景中;
  • addWidget(): 为部件创建一个QGraphicsProxyWidget并将其添加到场景中;
  • itemAt(): 返回指定位置上最顶层的图元;
  • items(): 返回场景中的所有图元;
  • render(): 将场景内容渲染到绘图设备(例如QImage)或者使用QPrinter进行打印;
  • selectedItems(): 返回当前所选定的图元列表;
  • selectionArea(): 返回先前使用setSelectionArea()设置的选择区域;如果未设置选择区域,则返回空QPainterPath。
  • setSelectionArea(): 根据指定的path设置选择区域设置。此区域内的所有项目都将立即被选中,而外部的所有项目都将未被选中;
  • clear(): 从场景中删除所有图元;
  • clearSelection(): 清除当前选择;
  • setBackgroundBrush(): 设置背景颜色。

QGraphicsScene常用信号:

  • changed: 如果场景内容发生更改,则发出此信号;
  • focusItemChanged: 每当场景中的焦点发生变化时(即,某项获得或失去输入焦点,或者当焦点从一个项目传递到另一个项目时),则发出此信号;
  • sceneRectChanged: 当场景矩形改变时,则发出此信号;
  • selectionChanged: 选择发生了改变时,则发出此信号。

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渲图输出图片

本文知识点

  • 使用QGraphicsPathItem为QGraphicsScene添加一个图元项;
  • 设置QGraphicsScene的背景;
  • QGraphicsScene渲染输出图像;
  • 了解QPaintDevice渲染设备。

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

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/21375.html

(0)
上一篇 2024-01-19 14:33
下一篇 2024-01-25 11:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信