PyQt 5: QPainter возвращает false при отображении QGraphicsScene в QImage - PullRequest
0 голосов
/ 11 октября 2018

В настоящее время я работаю над программой для отображения файлов журнала SIP-Trace.Он написан на Python 3.7 с использованием модуля PyQt 5 (.11.3) для загрузки и работы с графическим интерфейсом, созданным в QDesigner.В качестве основной функции он анализирует файл SIP-Trace и отображает его в виде диаграммы последовательности в QGraphicsScene с QGraphicsObjects.

Моя проблема заключается в следующем: для дальнейшего использования содержимое QGraphicsScene должно быть сохранено какфайл изображения, например .jpg или .png.В документации Qt / PyQt я нашел полезную звуковую команду QGraphicsScene.render () , которая отображает содержимое GraphicsScene в сохраняемый файл, такой как QImage, с использованием QPainter.В последние дни я пробовал пару способов / примеров кодов, найденных здесь и в других местах, но не могу отрисовать 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()

1 Ответ

0 голосов
/ 11 октября 2018

Проблема проста: в 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")

Вывод:

enter image description here

...