简体   繁体   English

将格式化文本从 QML 传递到 C++

[英]Pass formatted text from QML to C++

I have a simple pdf generator in my QML app, which uses C++ to receive a signal and write my PDF document to the device - when using a sample TestHtml.html document in the resources prints as intended, but I'm struggling to be able to send over custom HTML formatted text directly from the QML page. I have a simple pdf generator in my QML app, which uses C++ to receive a signal and write my PDF document to the device - when using a sample TestHtml.html document in the resources prints as intended, but I'm struggling to be able直接从 QML 页面发送自定义 HTML 格式的文本。

What I want to do我想做的事

My reportPage.qml displays varying data/information, when I click the 'download' button, it sends this formatted data to the C++ to print to PDF, (C++ is not my strong point).我的reportPage.qml显示不同的数据/信息,当我单击“下载”按钮时,它会将这些格式化的数据发送到 C++ 以打印到 PDF,(C++不是我的强项)

What I have tried我试过的

  • Using QIODevice to write to the.html file, effectively deleting/re-writing the data as needed使用QIODevice write .html文件,根据需要有效删除/重写数据
  • Using QString to pass my text from reportPage.qml as a string使用 QString 将我的文本从reportPage.qml作为字符串传递
  • Using QVariant to store my html as an array and pass as this from reportPage.qml使用 QVariant 将我的 html 存储为数组并从reportPage.qml

My only issue is, where c++ is not my strong point, all I get is errors in my pdf.cpp such as undeclared identifiers, no matching member function and so on so fourth我唯一的问题是,c++ 不是我的强项,我得到的只是我的pdf.cpp中的错误,例如未声明的标识符,没有匹配的成员 ZC1C425268E68385D1AB5074C17A94F14 等等

My Question is我的问题是

What is the best way to pass formatted html text using signals/slots form QML to C++ to print as a pdf using my pdf printer shown in the code below? What is the best way to pass formatted html text using signals/slots form QML to C++ to print as a pdf using my pdf printer shown in the code below?

At Current a simplified part of my code is:目前,我的代码的简化部分是:

reportPage.qml reportPage.qml

import Felgo 3.0
import com.allbookd.pdf 1.0
import QtQuick.Controls 1.2

Page {
    id: reportPage

    MyPdf {
        id: pdf
    }
    AppButton {
        text: "download"
        var htmlData = "<b>Hello</b> World 
                        <ul>
                            <li>Coffee</li>
                            <li>Tea</li>
                            <li>Milk</li>
                        </ul>"
        onClicked: { pdf.saveInvoice(htmlData); }
    }
}

pdf.h pdf.h

#ifndef PDF_H
#define PDF_H

#include <QObject>
#include <QDebug>
#include <QPainter>
#include <QTextDocument>
#include <QPdfWriter>
#include <QDate>
#include <QStandardPaths>
#include <QPrinter>
#include <QFile>

class pdf : public QObject
{
    Q_OBJECT
public:
    explicit pdf(QObject *parent = nullptr);

    void setCurrentDate();
    QString getCurrentDate() const;

signals:

    void invoiceSaved(int error);

public slots:
    QString getPdfPath() const;
    void saveInvoice();

private:
    QString currentDate;
    QString pdfPath;
};

#endif // PDF_H

pdf.cpp pdf.cpp


pdf::pdf(QObject *parent) : QObject(parent)
{
    setCurrentDate();
    QString path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
    pdfPath = path + "/invoice_" + getCurrentDate() + ".pdf";
}

void pdf::setCurrentDate()
{
    QDate date(QDate::currentDate());
    int day = date.day();
    int month = date.month();
    int year =  date.year();

    currentDate = QString::number(day) + "_" + QString::number(month) + "_" + QString::number(year);
}

QString pdf::getCurrentDate() const
{
    return currentDate;
}

QString pdf::getPdfPath() const
{
    return pdfPath;
}


void pdf::saveInvoice(QString htmlData)
{
    int error = 0;
    QPdfWriter pdfWriter(getPdfPath());

    pdfWriter.setPageSize(QPageSize(QPageSize::A4));

    QPainter painter(&pdfWriter);

    painter.scale(15.0, 15.0);

    QFile file(":/htmlcode.html");    //the HTML file from resources

    if(file.open(QIODevice::ReadWrite)) {
        QByteArray temp = file.readAll();   //read it all

        QString html = temp;                //convert it to QString
        QTextDocument doc;
        doc.setHtml(html);                  //set it as HTML

        doc.drawContents(&painter);         

    } else {
        qDebug() << "error: " << file.error();
        error = 1;
    }
    emit invoiceSaved(error);

}

You can expose your pdf class to QML.您可以将pdf class 暴露给 QML。 Make functions Q_INVOKABLE to be able to call them directly from QML or even better use Q_PROPERTY使函数 Q_INVOKABLE 能够直接从 QML 调用它们,甚至更好地使用 Q_PROPERTY

Docs for Q_INVOKABLE Docs for Q_PROPERTY Q_INVOKABLE的文档Q_PROPERTY的文档

Here is an example:这是一个例子:

Register/expose your pdf class to qml in main.cppmain.cpp中注册/公开您的 pdf class 到 qml

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "pdf.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    qmlRegisterType<pdf>("com.allbookd.pdf", 1, 0, "PdfPrinter");
    QQmlApplicationEngine engine;    
    ............

    return app.exec();
}

Make saveInvoice function invokable in pdf.h :使saveInvoice function 在pdf.h中可调用:

#include <QObject>

class pdf : public QObject
{
    Q_OBJECT
public:
    explicit pdf(QObject *parent = nullptr);

    void setCurrentDate();
    QString getCurrentDate() const;

    Q_INVOKABLE void saveInvoice(QString htmlData);

    ..............

And save htmlData to pdf using QPdfWriter:并使用 QPdfWriter 将htmlData保存到 pdf:

void pdf::saveInvoice(QString htmlData)
{
    int error = 0;
    QPdfWriter pdfWriter(getPdfPath());

    pdfWriter.setPageSize(QPageSize(QPageSize::A4));

    QPainter painter(&pdfWriter);
    painter.scale(15.0, 15.0);

    QTextDocument doc;
    doc.setHtml(htmlData);
    doc.drawContents(&painter);

    emit invoiceSaved(error);
}

Your QML could then look like that:您的 QML 可能看起来像这样:

import Felgo 3.0
import com.allbookd.pdf 1.0
import QtQuick.Controls 1.2

Page {
    id: reportPage
    property PdfPrinter pdf: PdfPrinter{}

    AppButton {
        text: "download"
        var htmlData = "<b>Hello</b> World 
                        <ul>
                            <li>Coffee</li>
                            <li>Tea</li>
                            <li>Milk</li>
                        </ul>"
        onClicked: { pdf.saveInvoice(htmlData); }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM