render a pygal graphic in a Qlabel

1

Good morning I'm trying to show a graph in a qlabel with pixmap and pygal, however it does not work, it throws me an error qn QPixmap

from PyQt5 import QtCore, QtWidgets, QtSvg
import pygal
from PyQt5 import uic
from PyQt5.QtGui import QPixmap


class Principal(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        uic.loadUi("1.ui",self)

        svg_widget = QtSvg.QSvgWidget()

        bar = pygal.Histogram()
        bar.add("Tabla", [1,2,3,4,5,6,7,8])
        data = bar.render()
        svg_widget.load(data)

        pixi = QPixmap.fromImage(svg_widget)
        self.label.setPixmap(pixi)
if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    p = Principal()
    p.show()
    p.resize(900,600)
    sys.exit(app.exec_())
    
asked by Mystic_Force 14.09.2018 в 17:47
source

1 answer

2

If you want to get from the data that returns the method render() of pygal you must use QSvgRenderer:

import pygal
from PyQt5 import QtCore, QtGui, QtWidgets, QtSvg, uic


class Principal(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        uic.loadUi("1.ui",self)

        hist = pygal.Histogram()
        hist.add('Wide bars', [(5, 0, 10), (4, 5, 13), (2, 0, 15)])
        hist.add('Narrow bars',  [(10, 1, 2), (12, 4, 4.5), (8, 11, 13)])
        data = hist.render()

        svg_render = QtSvg.QSvgRenderer(self)
        svg_render.load(data)

        pixmap = QtGui.QPixmap(svg_render.viewBox().size())
        pixmap.fill(QtCore.Qt.transparent)
        painter = QtGui.QPainter(pixmap)
        svg_render.render(painter)
        painter.end()

        self.label.setPixmap(pixmap)


if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    p = Principal()
    p.show()
    p.resize(900,600)
    sys.exit(app.exec_())

Another solution is to keep using QSvgWidget, but as you point out in the comments it does not appear inside the Qt Designer options, so in general if you want to use a widget that is not shown as an option, the solution is to promote the widget. To promote a widget the steps are as follows:

1. Drag an item that is close to the class you want to promote, in the case of QSvgWidget the closest widget is:

2. Right click, and in the menu select the option promote to ..

3. In the fields Promote Class Name place QSvgWidget and in Header File place PyQt5 / QtSvg, press the Add button and then the Promote button

The above generates the following ui:

1.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QSvgWidget" name="widget" native="true"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>24</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <customwidgets>
  <customwidget>
   <class>QSvgWidget</class>
   <extends>QWidget</extends>
   <header>PyQt5/QtSvg</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

With the above you can now use the QSvgWidget directly:

import pygal
from PyQt5 import QtCore, QtGui, QtWidgets, QtSvg, uic


class Principal(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        uic.loadUi("1.ui",self)

        hist = pygal.Histogram()
        hist.add('Wide bars', [(5, 0, 10), (4, 5, 13), (2, 0, 15)])
        hist.add('Narrow bars',  [(10, 1, 2), (12, 4, 4.5), (8, 11, 13)])
        data = hist.render()
        self.widget.load(data)


if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    p = Principal()
    p.show()
    p.resize(900,600)
    sys.exit(app.exec_())
    
answered by 14.09.2018 / 19:31
source