Я хочу получить HTML-код веб-страницы, открытой в QWebEngineView. Я использую функцию toHtml () в классе QWebEnginePage, как это
QWebEnginePage *page = ui->widget->page();
QString HTML = "";
page->toHtml([&HTML](QString html){qDebug() << "code \n\n\n" << html;});
HTML-код HTML-страницы появился в qDebug хорошо без проблем
проблема здесь в том, что когда я хочу использовать строку HTML вне функции, когда я показываю размер переменной HTML, она равна нулю и пуста
поэтому я попробовал это
QWebEnginePage *page = ui->widget->page();
QString HTML = "";
page->toHtml([&HTML](QString html){HTML = html;}); // crash
qDebug() << "i want to use HTML here outside the function = " << HTML;
но приложение показывает сбой, так что мне делать, чтобы я поместил данные HTML в переменную HTML, чтобы я мог использовать их вне функции
заранее спасибо
Ваша проблема вызвана тем, что лямбда работает асинхронно. Так что он действительно вызывается после выхода из метода, в котором вы вызываете toHtml
метод, и это также объясняет сбой — HTML
это локальная переменная в методе, которая уже вышла, так что лямбда случайным образом повреждает память, занятую HTML
переменная.
Здесь вы хотите синхронизировать вещи, т.е. блокировать ваш метод до тех пор, пока не будет выполнена лямбда. Это может быть сделано с QEventLoop
но для этого нужно будет отправить специальный сигнал от лямбды, чтобы указать, что лямбда закончила выполнение. Так что это будет выглядеть примерно так (не проверено):
class MyClass: public QObject
{
Q_OBJECT
public:
MyClass(QWebEnginePage & page, QObject * parent = 0);
void notifyHtmlReceived();
QString getHtml();
void setHtml(const QString & html) { m_html = html; }
Q_SIGNALS:
void htmlReceived();
private Q_SLOTS:
void requestHtmlFromPage();
private:
QWebEnginePage & m_page;
QString m_html;
};
MyClass::MyClass(QWebEnginePage & page, QObject * parent) :
QObject(parent),
m_page(page)
{}
void MyClass::notifyHtmlReceived()
{
emit htmlReceived();
}
QString MyClass::getHtml()
{
QEventLoop loop;
QObject::connect(this, SIGNAL(htmlReceived()), &loop, SLOT(quit()));
// Schedule the slot to run in 0 seconds but not right now
QTimer::singleShot(0, this, SLOT(requestHtmlFromPage()));
// The event loop would block until the lambda receiving the HTML is executed
loop.exec();
// If we got here, the html has been received and the result was saved in m_html
return m_html;
}
void MyClass::requestHtmlFromPage()
{
m_page.toHtml([this](QString html)
{
this->setHtml(html);
this->notifyHtmlReceived();
});
}
Других решений пока нет …