拦截QWebView弹出窗口
环境
系统:win7 64位旗舰版
软件:VS2013、QT5.5.1-32位
概述
当网页打开一个新的窗口时,我们有时候需要根据URL地址来判断弹出窗口是否合理,如果合理则弹出新窗口,否则不弹出。本文假设你能够基本使用QT。
步骤
1)首先创建类InterceptNetworkAccessManager
class InterceptNetworkAccessManager : public QNetworkAccessManager {
Q_OBJECT
public:
InterceptNetworkAccessManager() {}
void setIntercept(bool intercept) { m_intercept = intercept; }
signals:
// 拦截URL信号 [8/17/2016 Chao.Dong]
void signalInterceptUrl(const QUrl& url);
protected:
QNetworkReply* createRequest(QNetworkAccessManager::Operation op,
const QNetworkRequest &req,
QIODevice *outgoingData) override {
// 构造一个空的QNetworkRequest来拦截请求 [8/11/2016 Chao.Dong]
if (m_intercept) {
emit signalInterceptUrl(req.url());
return QNetworkAccessManager::createRequest(op, QNetworkRequest(), outgoingData);
}
return QNetworkAccessManager::createRequest(op, req, outgoingData);
}
private:
bool m_intercept = true;
};
该类的作用是拦截网络请求,因为在创建弹出窗口时,QT没有将加载的URL地址给我们,所以我们必须先自己截获请求,因为我们的目的只是为了获取URL地址,这里构造了一个空的请求是为了减小资源消耗。
2)让后创建类HiddenWebView
/** [8/17/2016 Chao.Dong]
* 隐藏的web窗口
*/
class HiddenWebView : public QWebView {
Q_OBJECT
public:
explicit HiddenWebView(QWidget* parent = NULL) {
QWebView::setVisible(false);
InterceptNetworkAccessManager* network = new InterceptNetworkAccessManager();
this->page()->setNetworkAccessManager(network);
connect(network, SIGNAL(signalInterceptUrl(const QUrl&)), this, SIGNAL(signalInterceptUrl(const QUrl&)), Qt::QueuedConnection);
}
virtual void setVisible(bool visible) {}
signals:
void signalInterceptUrl(const QUrl& url);
};
该类的作用是创建一个隐藏的web窗口,创建弹出的新窗口时,我们将隐藏web窗口给它之后,它会默认显示该窗口,而我们只是为了之后能获取新窗口的URL地址,所以并不需要显示。
3)最后创建WebView
/** [8/9/2016 Chao.Dong]
* Web窗口
*/
class WebView : public QWebView {
Q_OBJECT
public:
explicit WebView(QWidget* parent = NULL) {
this->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
}
virtual QWebView * createWindow(QWebPage::WebWindowType type) override {
switch (type)
{
case QWebPage::WebBrowserWindow:
HiddenWebView* web = new HiddenWebView();
connect(web, &HiddenWebView::signalInterceptUrl, [this, web](const QUrl& url) {
// 停止时会清除缓存 [8/11/2016 Chao.Dong]
web->stop();
web->deleteLater();
emit signalOpenWindow(url);
});
return web;
}
return QWebView::createWindow(type);
}
signals:
// 打开新链接 [8/15/2016 Chao.Dong]
void linkClicked(const QUrl& url);
// 打开新窗口信号 [8/9/2016 Chao.Dong]
void signalOpenWindow(const QUrl& url);
};
该类的作用是显示web窗口,并根据弹出新窗口的URL地址进行拦截。
结尾
最后的显示效果图: