使用 Lamda 从 QWebEngineView 中的 QWebEnginePage 获取 HTML
get HTML from QWebEnginePage in QWebEngineView using Lamda
我想获取在 QWebEngineView 中打开的网页的 HTML 代码 我在 QWebEnginePage 中使用 toHtml() 函数 Class 像这样
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 变量中,这样我就可以在函数外使用它
提前致谢
您的问题是由于 lambda 是 运行 异步的。所以它真的是在你退出调用 toHtml
方法的方法之后调用的,这也解释了崩溃 - HTML
是方法中的一个局部变量,它已经退出所以 lambda 只是随机损坏内存曾经被HTML
变量占用。
您想在这里做的是同步事情,即阻塞您的方法,直到执行 lambda。它可以用 QEventLoop
来完成,但这需要涉及从 lambda 发送一个特殊信号来指示 lambda 已完成执行的事实。所以它看起来有点像这样(未经测试):
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();
});
}
我想获取在 QWebEngineView 中打开的网页的 HTML 代码 我在 QWebEnginePage 中使用 toHtml() 函数 Class 像这样
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 变量中,这样我就可以在函数外使用它
提前致谢
您的问题是由于 lambda 是 运行 异步的。所以它真的是在你退出调用 toHtml
方法的方法之后调用的,这也解释了崩溃 - HTML
是方法中的一个局部变量,它已经退出所以 lambda 只是随机损坏内存曾经被HTML
变量占用。
您想在这里做的是同步事情,即阻塞您的方法,直到执行 lambda。它可以用 QEventLoop
来完成,但这需要涉及从 lambda 发送一个特殊信号来指示 lambda 已完成执行的事实。所以它看起来有点像这样(未经测试):
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();
});
}