so I wrote a programm for my thesis in Qt and now i am supposed to turn it into a working web assembly, which wasnt a real problem except for the filedownload part. I rewrote my filedownload method from:
QString costumfile::read(QString filename){
QString fileName = QFileDialog::getOpenFileName(nullptr, filename, "", "Text Files (*.txt )");
QFile file(filename);
qDebug()<<filename<<"filename";
if(!file.open(QFile::ReadOnly |
QFile::Text))
{
qDebug() << " Could not open the file for reading";
return "";
}
QTextStream in(&file);
QString myText = in.readAll();
//qDebug() << myText;
file.close();
return myText;
}
To this:
QString costumfile::read(QString filename)
{
QMessageBox msgBox;
QString textUser="Open" filename;
msgBox.setText(textUser);
msgBox.exec();
QString text="hallo";
qDebug()<<filename;
auto fileContentReady = [&](const QString &fileName, const QString &fileContent) {
if (fileName.isEmpty()) {
msgBox.setText("Error");
msgBox.exec();
} else {
text=fileContent;
qDebug()<<text<<"texstis";
return fileContent;
}
return fileContent;
};
QFileDialog::getOpenFileContent(".txt", fileContentReady);
}
and the problem is that the return doesnt wait for the lambda function because its asynch... I then tried using eventloops which works fine in the Destop applikation but isnt supported in the webassembly Applikation.
So does someone have a good idea how to wait for the fileContentReady Function?
CodePudding user response:
As far as I know, Qt for WebAssembly currently does not support waiting using event loops (at least Qt 6.2 does not). See Qt wiki:
"Nested event loops are not supported. Applications should not call e.g. QDialog::exec() or create a new QEventLoop object." https://wiki.qt.io/Qt_for_WebAssembly
So you would have to modify your method to handle the asynchronous call. What I mean is that whatever you want to do with the file, you can write directly into the fileContentReady lambda you have. If this is a generic function, you can let the caller register a done
callback to execute when the file is ready. Something like:
QString costumfile::read(QString filename,
const std::function<void(const QString&)>& done)
{
...
auto fileContentReady = [=](const QString &fileName, const QString &fileContent) {
if (fileName.isEmpty()) {
// Report error
} else {
text=fileContent;
qDebug()<<text<<"texstis";
done(text);
}
};
QFileDialog::getOpenFileContent(".txt", fileContentReady);
}
// When calling costumfile::read
read(filename, [=] (const QString& text) {
// Do something with `text`
});
Also, about the usage of QMessageBox exec()
. This can also cause problems as it internally creates a nested event loop which is not yet supported in Qt for WebAssembly. Instead use the show()
method.
auto msgBox = new QMessageBox();
msgBox->setText(textUser);
connect(msgBox, &QMessageBox::finished, &QMessageBox::deleteLater);
msgBox->show();