2016-07-17 25 views
1

QML Charts APIを試してみました。チャートビューをクリップボードに書き出すことにしました。私はJavascriptを通して画像としてアイテムをつかみ、QVariantデータをC++に送信する、ネット上でサーフィンしている実用的なソリューションを見つけました。これは素晴らしく、うまくいきますが、QQuickItem *やそれ以上のものを送信することはできないのでしょうか?皆さんはJavascriptを可能な限り避けて、イメージは重い操作のようです。QMLアイテムをクリップボードにコピーC++を使用して画像として

私は今使用している作業コードです。

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++に目的のItemを送信し、そこにあるすべてのものを処理するメソッドを呼び出すだけで、どのようにできるかについて考えていますか?



    Button{ 
       Layout.alignment: Qt.AlignBottom 
       text: qsTr("Copy to Clipboard") 
       onClicked: { 
         Printer.copyToClipboard(chart); 
       } 

      } 

答えて

0

私はC++でやり方を見つけました!

onClickedハンドラ(Javascript)内でPrinter.copyToClipboard(chart)を実行すると、実際にQObject *をC++レイヤに送信しています。私のC++メソッドの中で、私はqobject_castを実行してイメージとして取得できます。グラブ操作が非同期であることを考慮する必要があります。だから、私はクリップボードにコピーを行う必要があったスロット内のグラブが完了したときに呼び出されます。

ですから、以下は私が得た方法です。誰かがより良いアプローチをしていれば、それは知ってうれしいでしょう。

chartexporter.h



    #ifndef CHARTEXPORTER_H 
    #define CHARTEXPORTER_H 

    #include &ltQObject> 
    #include &ltQVariant> 
    #include &ltQSharedPointer> 

    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 &ltQDebug> 
    #include &ltQImage> 
    #include &ltQQuickItem> 
    #include &ltQClipboard> 
    #include &ltQApplication> 
    #include &ltQSharedPointer> 
    #include &ltQQuickItemGrabResult> 
    #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 &ltQApplication> 
    #include &ltQQmlContext> 
    #include &ltQQmlApplicationEngine> 
    #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(); 
    } 

関連する問題