将 QML 的 ChartView 保存到 PyQt5 中的图像文件
Saving QML's ChartView to image file in PyQt5
我的方法大致是这样的:
Chart.qml:
Window {
ChartView {
id: chartView
// ...
}
Button {
text: "save"
onClicked: manager.save(chartView)
}
}
Manager.py:
class Manager(QObject):
@pyqtSlot(QObject)
def save(self, chartview):
img = chartview.grab()
img.save(MY_DEFAULT_PATH)
当然,问题在于 Manager.save()
中的图表视图等同于没有 'grab' 方法的 C++ QObject*
。但它可以向下转换为 QChartView*
(或至少 QWidget*
),这种方法具有。在 C++ 中,我可能会使用 qobject_cast.
我的问题是:
- 这种向下转换在 PyQt 中可行吗?
- 如果没有 - 您知道如何以不同的方式完成吗?
在给出答案之前,最好澄清一下 post 的一些错误:
QML ChartView 是一个 Item,与 QChartView 不同,QChartView 是一个 QWidget。该项目是使用来自 QGraphicsScene 和 QChart 的信息绘制的。考虑到上述情况,一种方法可能是访问 QGraphicsScene 和 QChart,并使用 QGraphicsScene 的 render()
方法。
您可以通过 sip.cast()
方法使用 sip 进行转换。
在这种情况下,也没有必要进行向下转换,因为在签名中表明就足够了:
class Manager(QtCore.QObject):
@QtCore.pyqtSlot(QtQuick.QQuickItem)
def save(self, chartview):
self.result = chartview.grabToImage()
def handle_ready():
self.result.saveToFile(MY_DEFAULT_PATH)
delattr(self, "result")
self.result.ready.connect(handle_ready)
但是您可以使用 grabToImage 方法而不是变得太复杂,因为它是一个项目:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtCharts 2.2
ApplicationWindow {
visible: true
width: 640
height: 480
Button {
id: btn
text: "Save"
anchors.top: parent.top
onClicked: saveChart("chart.png")
}
ChartView {
id: chartView
anchors.top: btn.bottom
width: parent.width
anchors.bottom: parent.bottom
LineSeries {
XYPoint { x: 0; y: 0 }
XYPoint { x: 1.1; y: 2.1 }
}
}
function saveChart(filename){
chartView.grabToImage(function(result) {
result.saveToFile(filename);
});
}
}
我的方法大致是这样的:
Chart.qml:
Window {
ChartView {
id: chartView
// ...
}
Button {
text: "save"
onClicked: manager.save(chartView)
}
}
Manager.py:
class Manager(QObject):
@pyqtSlot(QObject)
def save(self, chartview):
img = chartview.grab()
img.save(MY_DEFAULT_PATH)
当然,问题在于 Manager.save()
中的图表视图等同于没有 'grab' 方法的 C++ QObject*
。但它可以向下转换为 QChartView*
(或至少 QWidget*
),这种方法具有。在 C++ 中,我可能会使用 qobject_cast.
我的问题是:
- 这种向下转换在 PyQt 中可行吗?
- 如果没有 - 您知道如何以不同的方式完成吗?
在给出答案之前,最好澄清一下 post 的一些错误:
QML ChartView 是一个 Item,与 QChartView 不同,QChartView 是一个 QWidget。该项目是使用来自 QGraphicsScene 和 QChart 的信息绘制的。考虑到上述情况,一种方法可能是访问 QGraphicsScene 和 QChart,并使用 QGraphicsScene 的
render()
方法。您可以通过
sip.cast()
方法使用 sip 进行转换。在这种情况下,也没有必要进行向下转换,因为在签名中表明就足够了:
class Manager(QtCore.QObject):
@QtCore.pyqtSlot(QtQuick.QQuickItem)
def save(self, chartview):
self.result = chartview.grabToImage()
def handle_ready():
self.result.saveToFile(MY_DEFAULT_PATH)
delattr(self, "result")
self.result.ready.connect(handle_ready)
但是您可以使用 grabToImage 方法而不是变得太复杂,因为它是一个项目:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtCharts 2.2
ApplicationWindow {
visible: true
width: 640
height: 480
Button {
id: btn
text: "Save"
anchors.top: parent.top
onClicked: saveChart("chart.png")
}
ChartView {
id: chartView
anchors.top: btn.bottom
width: parent.width
anchors.bottom: parent.bottom
LineSeries {
XYPoint { x: 0; y: 0 }
XYPoint { x: 1.1; y: 2.1 }
}
}
function saveChart(filename){
chartView.grabToImage(function(result) {
result.saveToFile(filename);
});
}
}