環境

系統: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地址進行攔截。

結尾

最後的顯示效果圖:

最後完成的Demo:InterceptOpenWindow.zip