I am trying to render styled pygal charts using Qt SVG renderer. But I still problems with background colors because it is black. Shouldn't it be controlled by the style of pygal chart? It should look like the first chart in http://www.pygal.org/en/stable/documentation/builtin_styles.html#darkstyle
我正在尝试使用Qt SVG渲染器渲染样式的pygal图表。但是我仍然有背景颜色的问题,因为它是黑色的。难道不应该由pygal图的风格来控制吗?它应该看起来像http://www.pygal.org/en/stable/documentation/builtin_styles.html#darkstyle的第一个图表。
import sys
import pygal
from PySide import QtGui, QtSvg
class Chart(QtGui.QWidget):
def __init__(self, parent=None):
super(Chart, self).__init__(parent)
chart = pygal.StackedLine(fill=True, interpolate='cubic',
style=pygal.style.DefaultStyle)
# or e.g. DarkSolarizedStyle
chart.add('A', [1, 3, 5, 16, 13, 3, 7])
chart.add('B', [5, 2, 3, 2, 5, 7, 17])
chart.add('C', [6, 10, 9, 7, 3, 1, 0])
chart.add('D', [2, 3, 5, 9, 12, 9, 5])
chart.add('E', [7, 4, 2, 1, 2, 10, 0])
svgSource = chart.render()
self.renderer = QtSvg.QSvgRenderer()
self.renderer.load(svgSource)
def paintEvent(self, event):
if self.renderer is not None:
painter = QtGui.QPainter(self)
self.renderer.render(painter)
return True
return super(Chart, self).paintEvent(event)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Chart()
window.show()
result = app.exec_()
sys.exit(result)
UPDATE: I get the same issue when using PyQt5, PyQt4, Pyside and also when using directly QSvgWidget. My suspicion is that it does not work because of failure in loading CSS files referenced in the SVG. Or it might be some limited scope of SVG specification which is supported by Qt as mentioned in Does QT support svg?.
更新:我在使用PyQt5、PyQt4、Pyside以及使用直接QSvgWidget时也会遇到同样的问题。我的怀疑是它不能工作,因为在SVG中引用的CSS文件的加载失败。或者它可能是一些有限的SVG规范的范围,Qt支持的Qt支持SVG ?
1 个解决方案
#1
1
OK, I have found the solution. The problem is that QtSvg
supports only a portion of the SVG functionality which is required to render SVGs created by pygal
. This is mentioned explicitly in Qt docs: "Qt supports the static features of SVG 1.2 Tiny. ECMA scripts and DOM manipulation are currently not supported." I think this is the reason why more complex SVGs are not being able to render using QtSvg
. Moreover QtSvg
is talked in discussions about as deprecated (though I have not found any official statement regarding this).
好的,我找到了解决方案。问题是,QtSvg只支持SVG功能的一部分,这是由pygal创建的SVGs所必需的。Qt文档中明确提到了这一点:“Qt支持SVG 1.2的静态特性。目前不支持ECMA脚本和DOM操作。我认为这就是为什么更复杂的SVGs不能使用QtSvg进行渲染的原因。此外,在讨论中,QtSvg也被讨论为弃用(尽管我还没有找到任何关于这个的正式声明)。
My solution is to use QtWebKit
(at the moment I need to support Qt4.8 so I am not using more moder QtWebEngine
module, which is expected to deprecate QtWebKit
in the near future in Qt5.x).
我的解决方案是使用QtWebKit(目前我需要支持Qt4.8,所以我没有使用更多的moder QtWebEngine模块,预计在Qt5.x的不久的将来会对QtWebKit提出质疑)。
The lines of code to show pygal
generated SVG are these:
显示pygal生成SVG的代码行如下:
chart = pygal.StackedLine(...
...
window = QtWebKit.QWebView()
window.setContent(chart.render())
window.show()
UPDATE: Qt is going to deprecate QtWebKit
soon. Also the import modules for PySide/PyQt4 and PyQt5 are different. In order to make it work, you need to use some of these QtWebKit.QWebView
(PySide, PyQt4), QtWebKitWidgets.QWebView
(older PyQt5), QtWebEngine.QWebEngineView
(probably PySide2 - have not tested) and QtWebEngineWidgets.QWebEngineView
(modern PyQt5). By 'modern' I roughly mean Qt version >= 5.5.
更新:Qt将很快取消QtWebKit。另外,PySide/PyQt4和PyQt5的导入模块也不同。为了使它有效,您需要使用一些QtWebKit。QWebView(PySide PyQt4),QtWebKitWidgets。QtWebEngine QWebView(老PyQt5)。QWebEngineView(可能是PySide2 -没有测试)和QtWebEngineWidgets。QWebEngineView(现代PyQt5)。“modern”的意思是Qt版本>= 5.5。
Regarding rendering of pygal
charts, QtWebKit
does not support all dynamic features, while QtWebEngine
does. The drawback of QtWebEngine
is much slower startup.
关于pygal图表的绘制,QtWebKit不支持所有的动态特性,而QtWebEngine则支持。QtWebEngine的缺点是启动慢得多。
#1
1
OK, I have found the solution. The problem is that QtSvg
supports only a portion of the SVG functionality which is required to render SVGs created by pygal
. This is mentioned explicitly in Qt docs: "Qt supports the static features of SVG 1.2 Tiny. ECMA scripts and DOM manipulation are currently not supported." I think this is the reason why more complex SVGs are not being able to render using QtSvg
. Moreover QtSvg
is talked in discussions about as deprecated (though I have not found any official statement regarding this).
好的,我找到了解决方案。问题是,QtSvg只支持SVG功能的一部分,这是由pygal创建的SVGs所必需的。Qt文档中明确提到了这一点:“Qt支持SVG 1.2的静态特性。目前不支持ECMA脚本和DOM操作。我认为这就是为什么更复杂的SVGs不能使用QtSvg进行渲染的原因。此外,在讨论中,QtSvg也被讨论为弃用(尽管我还没有找到任何关于这个的正式声明)。
My solution is to use QtWebKit
(at the moment I need to support Qt4.8 so I am not using more moder QtWebEngine
module, which is expected to deprecate QtWebKit
in the near future in Qt5.x).
我的解决方案是使用QtWebKit(目前我需要支持Qt4.8,所以我没有使用更多的moder QtWebEngine模块,预计在Qt5.x的不久的将来会对QtWebKit提出质疑)。
The lines of code to show pygal
generated SVG are these:
显示pygal生成SVG的代码行如下:
chart = pygal.StackedLine(...
...
window = QtWebKit.QWebView()
window.setContent(chart.render())
window.show()
UPDATE: Qt is going to deprecate QtWebKit
soon. Also the import modules for PySide/PyQt4 and PyQt5 are different. In order to make it work, you need to use some of these QtWebKit.QWebView
(PySide, PyQt4), QtWebKitWidgets.QWebView
(older PyQt5), QtWebEngine.QWebEngineView
(probably PySide2 - have not tested) and QtWebEngineWidgets.QWebEngineView
(modern PyQt5). By 'modern' I roughly mean Qt version >= 5.5.
更新:Qt将很快取消QtWebKit。另外,PySide/PyQt4和PyQt5的导入模块也不同。为了使它有效,您需要使用一些QtWebKit。QWebView(PySide PyQt4),QtWebKitWidgets。QtWebEngine QWebView(老PyQt5)。QWebEngineView(可能是PySide2 -没有测试)和QtWebEngineWidgets。QWebEngineView(现代PyQt5)。“modern”的意思是Qt版本>= 5.5。
Regarding rendering of pygal
charts, QtWebKit
does not support all dynamic features, while QtWebEngine
does. The drawback of QtWebEngine
is much slower startup.
关于pygal图表的绘制,QtWebKit不支持所有的动态特性,而QtWebEngine则支持。QtWebEngine的缺点是启动慢得多。