将QML项目复制到剪贴板作为图像通过C ++

时间:2016-07-17 15:23:48

标签: c++ qt charts export qml

我一直在尝试使用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);
                }

            }

1 个答案:

答案 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();
    }