Python PyQt 5:QPaint在将QGraphicscene渲染到QImage时返回false
目前我正在开发一个程序,用于显示SIP跟踪日志文件。它是用Python 3.7编写的,使用PyQt 5(.11.3)模块加载和操作QDesigner中的GUI。作为一项主要功能,它解析SIP跟踪文件,并将其显示为带有QGraphicsObject的QGraphicscene的序列图 我的问题在于:为了以后参考,qgraphicscene的内容应该保存为图像文件,如.jpg或.png。在Qt/PyQt文档中,我发现了一个有用的命令,它使用QPainter将graphicscene的内容呈现到一个可保存的文件中,比如QImage。在过去的几天里,我尝试了这里和其他地方的几种方法/示例代码,但无法将Graphicscene渲染到QImage,更不用说渲染到图像文件了。由于我对Python和Qt相当陌生,我想我在某些地方缺少一些基本设置。以下是我的代码的最低版本Python PyQt 5:QPaint在将QGraphicscene渲染到QImage时返回false,python,python-3.x,pyqt5,qgraphicsscene,qpainter,Python,Python 3.x,Pyqt5,Qgraphicsscene,Qpainter,目前我正在开发一个程序,用于显示SIP跟踪日志文件。它是用Python 3.7编写的,使用PyQt 5(.11.3)模块加载和操作QDesigner中的GUI。作为一项主要功能,它解析SIP跟踪文件,并将其显示为带有QGraphicsObject的QGraphicscene的序列图 我的问题在于:为了以后参考,qgraphicscene的内容应该保存为图像文件,如.jpg或.png。在Qt/PyQt文档中,我发现了一个有用的命令,它使用QPainter将graphicscene的内容呈现到一个可
# -*- 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)
因此无法生成图像,解决方案是创建一个大小为:
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")
输出: