我一直在尝试使用QML Charts API,并决定将ChartView作为图像导出到剪贴板。我找到了一个在网上冲浪的工作解决方案,其中一个通过Javascript抓取项目作为图像,并将QVariant数据发送到C ++。这很好并且有效,但是我想知道是否有可能只发送一个QQuickItem *或者像它那样轻松的东西,并且在C ++中执行抓取和任何操作,因为每个人都说避免Javascript这么多尽可能抓住一个图像似乎是一个沉重的操作。
以下是我现在使用的工作代码。
chartexporter.h
#ifndef CHARTEXPORTER_H
#define CHARTEXPORTER_H
#include
#include
class QQuickItem;
class ChartExporter : public QObject
{
Q_OBJECT
public:
explicit ChartExporter(QObject *parent = 0);
Q_INVOKABLE void copyToClipboard(QVariant data);
};
#endif // CHARTEXPORTER_H
chartexporter.cpp
includes....
ChartExporter::ChartExporter(QObject *parent) : QObject(parent)
{
}
void ChartExporter::copyToClipboard(QVariant data){
QImage img = qvariant_cast(data);
QApplication::clipboard()->setImage(img,QClipboard::Clipboard);
}
main.qml
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import QtCharts 2.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello Chart World")
ColumnLayout{
spacing: 2
anchors.fill: parent
ChartView{
id: chart
title: "Testing Charts"
anchors.fill: parent
legend.alignment: Qt.AlignTop
antialiasing: true
animationOptions: ChartView.AllAnimations
PieSeries {
id: pieSeries
PieSlice { label: "Volkswagen"; value: 13.5; exploded: true}
PieSlice { label: "Toyota"; value: 10.9 }
PieSlice { label: "Ford"; value: 8.6 }
PieSlice { label: "Skoda"; value: 8.2 }
PieSlice { label: "Volvo"; value: 6.8 }
}
}
Button{
Layout.alignment: Qt.AlignBottom
text: qsTr("Copy to Clipboard")
onClicked: {
var stat = chart.grabToImage(function(result) {
Printer.copyToClipboard(result.image);
});
}
}
}
}
的main.cpp
includes ....
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
ChartExporter printer;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("Printer", &printer);
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}
您是否知道如何通过简单地调用方法将所需的项目发送到C ++,如下所述并处理其中的所有内容?
Button{
Layout.alignment: Qt.AlignBottom
text: qsTr("Copy to Clipboard")
onClicked: {
Printer.copyToClipboard(chart);
}
}
答案 0 :(得分:2)
我找到了一种用C ++做的方法!
当我在onClicked处理程序(Javascript)中执行Printer.copyToClipboard(图表)时,我实际上是将QObject *发送到C ++层。在我的C ++方法中,我可以做一个qobject_cast并将其作为图像抓取。必须考虑到抓取操作是异步的。所以,我需要在一个插槽内复制到剪贴板,当抓取完成后调用它。
所以,下面是我得到的方式。如果有人有更好的方法,那么很高兴知道。
chartexporter.h
#ifndef CHARTEXPORTER_H
#define CHARTEXPORTER_H
#include <QObject>
#include <QVariant>
#include <QSharedPointer>
class QQuickItem;
class QQuickItemGrabResult;
class ChartExporter : public QObject
{
Q_OBJECT
private:
QSharedPointer p_grabbedImage;
protected slots:
void doCopy();
public:
explicit ChartExporter(QObject *parent = 0);
Q_INVOKABLE void copyToClipboard(QObject *item);
};
#endif // CHARTEXPORTER_H
chartexporter.cpp
#include <QDebug>
#include <QImage>
#include <QQuickItem>
#include <QClipboard>
#include <QApplication>
#include <QSharedPointer>
#include <QQuickItemGrabResult>
#include "chartexporter.h"
ChartExporter::ChartExporter(QObject *parent) : QObject(parent), p_grabbedImage(nullptr)
{
}
void ChartExporter::copyToClipboard(QObject* item){
if(item){
auto itm = qobject_cast(item);
p_grabbedImage = itm->grabToImage(QSize(itm->width()*2,itm->height()*2));
connect(p_grabbedImage.data(), &QQuickItemGrabResult::ready, this, &ChartExporter::doCopy);
}
}
void ChartExporter::doCopy(){
if(p_grabbedImage.data()){
auto img = p_grabbedImage->image();
QApplication::clipboard()->setImage(img, QClipboard::Clipboard);
}
disconnect(p_grabbedImage.data(),&QQuickItemGrabResult::ready, this, &ChartExporter::doCopy);
}
main.qml
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import QtCharts 2.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello Chart World")
ColumnLayout{
spacing: 2
anchors.fill: parent
ChartView{
id: chart
title: "Testing Charts"
anchors.fill: parent
legend.alignment: Qt.AlignTop
antialiasing: true
animationOptions: ChartView.AllAnimations
PieSeries {
id: pieSeries
PieSlice { label: "Volkswagen"; value: 13.5; exploded: true}
PieSlice { label: "Toyota"; value: 10.9 }
PieSlice { label: "Ford"; value: 8.6 }
PieSlice { label: "Skoda"; value: 8.2 }
PieSlice { label: "Volvo"; value: 6.8 }
}
}
Button{
Layout.alignment: Qt.AlignBottom
text: qsTr("Copy to Clipboard")
onClicked: {
Printer.copyToClipboard(chart);
}
}
}
}
的main.cpp
#include <QApplication>
#include <QQmlContext>
#include <QQmlApplicationEngine>
#include "chartexporter.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
ChartExporter printer;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("Printer", &printer);
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}