问题描述
我的方法大致如此:
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()
内部,图表视图等效于C ++的QObject*
,后者没有'grab'方法。但是可以将其向下转换为这种方法具有的QChartView*
(或至少为QWidget*
)。在C ++中,我可能会用qobject_cast做到这一点。
我的问题是:
- 在PyQt中这种向下转换是否可行?
- 如果没有-您是否知道如何以不同的方式进行操作?
解决方法
在给出答案之前,最好先阐明帖子中的一些错误:
-
QML ChartView是一个与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)
但是,因为它是Item,所以可以使用catchToImage方法,而不是变得太复杂:
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);
});
}
}