2016-07-17 10 views
1

Ich habe versucht mit QML Charts API und entschied sich, das ChartView als Bild in die Zwischenablage zu exportieren. Ich habe eine funktionierende Lösung gefunden, die im Netz surft, in der man den Gegenstand als Bild durch Javascript ergreift und die QVariant-Daten an C++ sendet. Das ist nett und funktioniert, aber ich frage mich, ob es nicht möglich wäre, nur ein QQuickItem * oder etwas so leichtes zu senden und den Greifer und was auch immer in C++ zu tun, wie jeder sagt, um Javascript so viel wie möglich zu vermeiden und zu greifen Ein Bild scheint eine schwere Operation zu sein.Kopiere QML Item in die Zwischenablage als Bild durch C++

Hier ist der Arbeitscode, den ich jetzt verwende.

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

Habt ihr eine Vorstellung davon, wie man das machen könnte, indem man einfach eine Methode aufruft, um das gewünschte Item wie unten beschrieben an C++ zu senden und alle Sachen dort zu verarbeiten?



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

      } 

Antwort

0

Ich habe eine Art gefunden, es in C++ zu tun!

Wenn ich die Printer.copyToClipboard (Diagramm) innerhalb der OnClicked-Handler (Javascript) mache ich tatsächlich ein QObject * an die C++ - Schicht senden. Innerhalb meiner C++ Methode kann ich einen qobject_cast machen und ihn als Bild aufnehmen. Zu beachten ist, dass der Greiferbetrieb asynchron ist. Also musste ich die Kopie in die Zwischenablage in einem Slot kopieren, der aufgerufen wird, wenn der Greifer fertig ist.

Also, unten ist der Weg, den ich bekam. Wenn jemand einen besseren Ansatz hat, wäre es schön zu wissen.

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

Verwandte Themen