• 拦截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地址进行拦截。

    结尾

    最后的显示效果图:

    最后完成的Demo:InterceptOpenWindow.zip

  • 相关阅读:
    Vuejs
    Vuejs
    Vuejs
    Vuejs
    JS高级之面试必须知道的几个点
    用vue快速开发app的脚手架工具
    作为一名前端开发工程师,你必须掌握的WEB模板引擎:Handlebars
    REST接口设计规范总结
    eclipse实现JavaWeb应用增量打包
    转载:作为面试官,我是怎么快速判断程序员能力的?
  • 原文地址:https://www.cnblogs.com/dongc/p/5786199.html
Copyright © 2020-2023  润新知