I'm trying to create an HTML file using Qt C++, and then save it to a PDF file. So far I have succeeded creating an HTML file, but when I try to save it to a PDF file, I get a warning about D3D11 Live Object in my console, and the PDF file won't be created.
I also noticed that it works in release mode, but not debug mode. Why is that?
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWebEngineView>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void generatePdf();
private slots:
void onLoadFinished(bool);
private:
Ui::MainWindow *ui;
QWebEngineView *view;
void createHtmlFile();
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QWebEngineSettings>
#include <QCoreApplication>
#include <QDir>
#include <QDebug>
#include <QMessageBox>
#include <QFileDialog>
#include <QStandardPaths>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
createHtmlFile(); // Create the HTML file
view = new QWebEngineView(this);
connect(view, &QWebEngineView::loadFinished, this, &MainWindow::onLoadFinished);
QString htmlFilePath = QCoreApplication::applicationDirPath() + "/index.html"; //Returns the directory that contains the application executable
qDebug() << "Loading HTML file from: " << htmlFilePath;
view->setUrl(QUrl::fromLocalFile(htmlFilePath));
setCentralWidget(view);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::createHtmlFile()
{
QString htmlFilePath = QCoreApplication::applicationDirPath() + "/index.html"; //Returns the directory that contains the application executable
QFile file(htmlFilePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
qDebug() << "Failed to open file for writing: " << file.errorString();
QMessageBox::warning(this, "File Error", "Failed to create HTML file: " + file.errorString());
return;
}
QTextStream out(&file);
out << "<!DOCTYPE html>\n";
out << "<html lang=\"en\">\n";
out << "<head>\n";
out << "<meta charset=\"UTF-8\">\n";
out << "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n";
out << "<title>QWebEngine Example</title>\n";
out << "</head>\n";
out << "<body>\n";
out << "<h1>Hello from QWebEngine!</h1>\n";
out << "<p>This is a simple HTML page loaded using Qt's QWebEngine.</p>\n";
out << "</body>\n";
out << "</html>\n";
file.close();
qDebug() << "HTML file created successfully at: " << htmlFilePath;
}
void MainWindow::onLoadFinished(bool ok)
{
if (ok)
{
qDebug() << "HTML file loaded successfully.";
generatePdf(); // Generate the PDF once the HTML is loaded
}
else
{
qDebug() << "Failed to load HTML file.";
QMessageBox::warning(this, "Load Error", "Failed to load the HTML file.");
}
}
void MainWindow::generatePdf() //Does not work
{
QString pdfFilePath = QFileDialog::getSaveFileName(this, tr("Save PDF"),
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
tr("PDF Files (*.pdf)"));
if (pdfFilePath.isEmpty())
return;
view->page()->printToPdf(pdfFilePath);
}
main.cpp
#include "MainWindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
The PDF file will NOT be created. Here's what my console looks like after I run my program:
> HTML file created successfully at:
> "C:/Users/someUser/Documents/build-HTMLtoPDF-Desktop_Qt_6_6_1_MSVC2019_64bit-Debug/debug/index.html"
> Loading HTML file from:
> "C:/Users/someUser/Documents/build-HTMLtoPDF-Desktop_Qt_6_6_1_MSVC2019_64bit-Debug/debug/index.html"
> doh set to "" -- SystemOnly HTML file loaded successfully. D3D11
> WARNING: ID3D11Device::CreateInputLayout: The provided input signature
> expects to read an element with SemanticName/Index: 'TEXCOORD'/2 and
> component(s) of the type 'int32'. However, the matching entry in the
> Input Layout declaration, element[2], specifies mismatched format:
> 'R16G16_UINT'. This is not an error, since behavior is well defined:
> The element format determines what data conversion algorithm gets
> applied before it shows up in a shader register. Independently, the
> shader input signature defines how the shader will interpret the data
> that has been placed in its input registers, with no change in the
> bits stored. It is valid for the application to reinterpret data as a
> different type once it is in the vertex shader, so this warning is
> issued just in case reinterpretation was not intended by the author. [
> STATE_CREATION WARNING #391: CREATEINPUTLAYOUT_TYPE_MISMATCH] Received
> fatal exception EXCEPTION_BREAKPOINT Backtrace:
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74F19CE8+276867377] invalid_parameter
> [0x00007FFBBB30AF0F+207] QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7B758B88+386176977]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7B7584FD+386175302]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7B75855D+386175398]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7B758431+386175098]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7B75874A+386175891]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7B74A113+386116956]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E226B7+477180672]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E22A6B+477181620]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E28B1C+477206373]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E14C7B+477124804]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E1561C+477127269]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E169B0+477132281]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E2FAE6+477234991]
> QWebEnginePage::setUrlRequestInterceptor [0x00007FFB64F6E615+8778334]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E2067E+477172423]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E2232C+477179765]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E2942B+477208692]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E2CAB2+477222651]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74B63F9F+272976872]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E1CEF5+477158206]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7677ACDA+302430499]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB76778993+302421468]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB767BB198+302693857]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7677A0A8+302427377]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB77252F2F+313801592]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB77246F0B+313752404]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB77247625+313754222]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB77247A60+313755305]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB77258336+313823103]
> QWebEnginePage::setUrlRequestInterceptor [0x00007FFB64F6E615+8778334]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74D1D637+274784896]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74EC31F7+276512320]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74ED6B35+276592510]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74ED5A3F+276588168]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74C64226+274026095]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74EE1438+276635777]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74E714AD+276177142]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7BABB1FD+389725766]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7328538C+246898645]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB73283F90+246893529]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7327D0D1+246865178]
> QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB73277D3D+246843782]
> QWebEnginePage::setUrlRequestInterceptor [0x00007FFB64FEF25E+9305767]
> TargetGetStockObject [0x00007FF6E9FA49A3+287028]
> TargetGetStockObject [0x00007FF6EA726CE7+8160376]
> TargetGetStockObject [0x00007FF6EA726AEE+8159871]
> TargetGetStockObject [0x00007FF6EA71E492+8125475]
> TargetGetStockObject [0x00007FF6EA71E33E+8125135]
> TargetGetStockObject [0x00007FF6EA71E1FE+8124815]
> TargetGetStockObject [0x00007FF6EA71E52E+8125631]
> BaseThreadInitThunk [0x00007FFC305A7344+20] RtlUserThreadStart
> [0x00007FFC31B226B1+33]
> [25992:22332:0514/155233.091:INFO:web_contents_delegate_qt.cpp(279)]
> ProcessGone: 3 (-2147483645)
> [25992:22332:0514/155233.091:INFO:web_contents_delegate_qt.cpp(279)]
> ProcessGone: 3 (-2147483645)
How do I solve this?
This is a bug with Qt versions < 6.7.0, because in testing with Qt 6.7.1, the PDF file generates fine.
See:
Fixed in Qt 6.7.0 as mentioned in its release notes.
It's possible to use this minimal example to test different versions:
#include <QApplication>
#include <QWebEngineView>
#include <QFile>
#include <QTextStream>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QString path = QCoreApplication::applicationDirPath();
QFile file(path+"/example.html");
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
qDebug() << "Failed to open file for writing: " << file.errorString();
return -1;
}
QTextStream out(&file);
out << "<!DOCTYPE html> <html> <body> <h1>Example HTML FILE</h1> </body> </html>";
file.close();
QWebEngineView view;
QObject::connect(&view, &QWebEngineView::loadFinished, [&view, &path](bool ok)
{
if (ok)
{
qDebug() << "HTML file loaded successfully.";
view.page()->printToPdf(path+"/examplePDF.pdf");
}
else
{
qDebug() << "Failed to load HTML file.";
}
});
view.setUrl(QUrl::fromLocalFile(path+"/example.html"));
view.show();
return a.exec();
}