繁体   English   中英

PyQt 5:将QGraphicsScene渲染到QImage时,QPainter返回false

[英]PyQt 5: QPainter returns false while rendering QGraphicsScene to a QImage

目前,我正在开发一个程序,以显示SIP-Trace日志文件。 它是使用PyQt 5(.11.3)模块以python 3.7编写的,以加载和操作QDesigner中制作的GUI。 它的主要功能是解析SIP-Trace文件,并将其作为序列图显示给具有QGraphicsObjects的QGraphicsScene。

我的问题出在以下方面:供以后参考,QGraphicsScene的内容应另存为图像文件,例如.jpg或.png。 在Qt / PyQt文档中,我找到了有用的探测命令QGraphicsScene.render() ,该命令使用QPainter将GraphicsScene的内容呈现为可保存的文件(如QImage)。 在过去的几天里,我尝试了几种在此处和其他地方找到的方法/示例代码,但是无法将GraphicsScene渲染到QImage到图像文件。 由于我是Python和Qt的新手,因此我认为某些地方缺少一些基本设置。 以下是我的代码的最低版本。

# -*- coding: utf8 -*-
"""Class for getting a sequence diagram of a sip traffic"""

from PyQt5.QtWidgets import *
from PyQt5 import uic
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys


class VoipGui(QMainWindow):
    """ Class that handles the interaction with the UI """
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = uic.loadUi("main_window.ui", self)
        self.showMaximized()

        self.sequence_scene = QGraphicsScene()
        self.ui.graphicsView.setScene(self.sequence_scene)
        # self.sequence_scene.setSceneRect(0, 0, 990, 2048)

        # sets the spacing between nodes
        # For more than three nodes columns should be generated in a more automatic way
        self.left_column = 51
        self.middle_column = 381
        self.right_column = 711
        self.flow_height = 60  # Sets the spacing between the arrows in the flowchart

        # --------------------------------- /class init and var set -------------------------------------------

        self.actionOpenFile.triggered.connect(self.on_open_file)
        self.actionCloseFile.triggered.connect(self.on_close_file)
        self.actionCloseProgram.triggered.connect(self.close)
        self.actionSaveFile.triggered.connect(self.save_seq_image)

        # --------------------------------- /connecting slots and signals ----------------------------

    def on_open_file(self):
        """Dummy version of the open file dialog"""
        self.draw_node(self.left_column, 5, "192.168.2.1", 10)
        self.draw_node(self.middle_column, 5, "192.168.2.22", 10)

    def on_close_file(self):
        self.ui.textBrowser.clear()
        self.sequence_scene.clear()

    def save_seq_image(self):
        """ Here lies the problem: Save the rendered sequence scene to file for later use"""
        rect_f = self.sequence_scene.sceneRect()
        # rect = self.sequence_scene.sceneRect().toRect()
        # img = QPixmap(rect.size())

        img = QImage()
        p = QPainter()

        # p.setPen(QColor(255, 255, 255))
        # p.setViewport(rect)

        painting = p.begin(img)
        self.sequence_scene.render(p, target=QRectF(img.rect()), source=rect_f)
        p.end()

        if painting:
            print("Painter init pass")
        elif not painting:
            print("Painter init fail")

        saving = img.save("save.jpg")
        if saving:
            print("Saving Pass")
        elif not saving:
            print("Saving Not Pass")

    def draw_node(self, x_pos, y_pos, ip_address, y_stops):
        """Participating devices are displayed as these nodes"""
        width = 100.0
        height = 40.0
        pc_box = QGraphicsRectItem(x_pos - 50, y_pos, width, height)
        self.sequence_scene.addItem(pc_box)
        pc_ip = QGraphicsTextItem("%s" % ip_address)
        pc_ip.setPos(x_pos - 50, y_pos)
        self.sequence_scene.addItem(pc_ip)
        node_line = QGraphicsLineItem(x_pos, y_pos + 40, x_pos, y_pos + (y_stops * self.flow_height))
        self.sequence_scene.addItem(node_line)


def show_window():
    app = QApplication(sys.argv)
    dialog = VoipGui()
    dialog.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    show_window()

问题很简单,在render()您指示目标的大小等于QImage大小,并且QImage的大小如何?您如何使用QImage()的大小是QSize(0, 0)所以它无法生成图像,解决方法是创建一个大小为QImage的图像:

def save_seq_image(self):
    """ Here lies the problem: Save the rendered sequence scene to file for later use"""
    rect_f = self.sequence_scene.sceneRect()
    img = QImage(QSize(640, 480), QImage.Format_RGB888)
    img.fill(Qt.white)
    p = QPainter(img)
    self.sequence_scene.render(p, target=QRectF(img.rect()), source=rect_f)
    p.end()
    saving = img.save("save.jpg")
    print("Saving Pass" if saving else "Saving Not Pass")

输出:

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM