Webengine - open in external browser



  • Hi All -

    I'm currently migrating my application from QtWebKit to QtWebEngine. The transition has mostly been smooth, but there are a couple things I'm trying to figure out how to duplicate. One thing I used to do was set links to open in the user's external browser. Something like "Click here for more info" and it would direct them to the external site in chrome/explorer/safari/etc. I did this via:

    ui->map->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks)
    connect( ui->map->page(), SIGNAL(linkClicked(const QUrl &)),this, SLOT(OpenExternalBrowser(const QUrl &)));
    

    I saw in the documentation it mentions overloading the QWebEnginePage::acceptNavigationRequest() function, however, I'm not totally sure how to achieve the behavior there.

    Thanks for the help



  • Correct, you add the acceptNavigationRequest() to your QWebEnginePage derived class, then supply the guts for the function to open the user's default browser.
    E.g.:

    class MyWebPage : public QWebEnginePage
    {
    	Q_OBJECT
    
    public:
    	MyWebPage(QObject* parent = 0) : QWebEnginePage(parent){}
    
    	bool acceptNavigationRequest(const QUrl & url, QWebEnginePage::NavigationType type, bool isMainFrame)
    	{
    		 qDebug() << "acceptNavigationRequest("<<url << "," << type << "," << isMainFrame<<")";
    
    		if (type == QWebEnginePage::NavigationTypeLinkClicked)
    		{
    			QDesktopServices::openUrl(url);
    			return false;
    		}
    		return true;
    	}
    }
    
    


  • Thanks. I think I'm getting there, but still having some troubles. In the end, this all ends up in a QWebEngineView widget. So I've done the following:

    myqwebenginepage.h

    #include <QWebEnginePage>
    
    class MyQWebEnginePage : public QWebEnginePage
    {
        Q_OBJECT
    public:
        MyQWebEnginePage(QObject* parent = 0);
        bool acceptNavigationRequest(const QUrl & url, QWebEnginePage::NavigationType type, bool isMainFrame);
    };
    

    myqwebenginepage.cpp

    #include "myqwebenginepage.h"
    #include <QDesktopServices>
    
    MyQWebEnginePage::MyQWebEnginePage(QObject* parent)
    {
    
    }
    
    bool MyQWebEnginePage::acceptNavigationRequest(const QUrl & url, QWebEnginePage::NavigationType type, bool isMainFrame)
    {
         qDebug() << "acceptNavigationRequest("<<url << "," << type << "," << isMainFrame<<")";
    
        if (type == QWebEnginePage::NavigationTypeLinkClicked)
        {
            QDesktopServices::openUrl(url);
            return false;
        }
        return true;
    }
    
    

    myqwebengineview.h

    #include <QWebEngineView>
    #include <myqwebenginepage.h>
    
    class MyQWebEngineView : public QWebEngineView
    {
        Q_OBJECT
    public:
        explicit MyQWebEngineView(QWidget* parent = 0);
        MyQWebEnginePage* page() const;
    };
    
    

    myqwebengineview.cpp

    #include "myqwebengineview.h"
    
    MyQWebEngineView::MyQWebEngineView(QWidget* parent)
    {
    
    }
    

    I then go into my UI file and flip out qwebengineview with myqwebengineview widget. The result is a series of unresolved externals, but I'm not sure why.

    MyApp_main.obj:-1: error: LNK2001: unresolved external symbol "public: class MyQWebEnginePage * __cdecl MyQWebEngineView::page(void)const " (?page@MyQWebEngineView@@QEBAPEAVMyQWebEnginePage@@XZ)
    

    Thanks again for your help



  • After some more light reading, I've wound up with this:

    class MyQWebEnginePage : public QWebEnginePage
    {
        Q_OBJECT
    
    public:
        MyQWebEnginePage(QObject* parent = 0) : QWebEnginePage(parent){qDebug() << "here";}
    
        bool acceptNavigationRequest(const QUrl & url, QWebEnginePage::NavigationType type, bool isMainFrame)
        {
             qDebug() << "acceptNavigationRequest("<<url << "," << type << "," << isMainFrame<<")";
    
            if (type == QWebEnginePage::NavigationTypeLinkClicked)
            {
                QDesktopServices::openUrl(url);
                return false;
            }
            return true;
        }
    };
    
    class MyQWebEngineView : public QWebEngineView
    {
        Q_OBJECT
    
    public:
        MyQWebEngineView(QWidget* parent = 0) : QWebEngineView(parent){}
        MyQWebEnginePage* page() const;
    };
    

    Still getting a similar error in my test application though. Getting warmer?

    mainwindow.obj:-1: error: LNK2019: unresolved external symbol "public: class MyQWebEnginePage * __cdecl MyQWebEngineView::page(void)const " (?page@MyQWebEngineView@@QEBAPEAVMyQWebEnginePage@@XZ) referenced in function "public: __cdecl MainWindow::MainWindow(class QWidget *)" (??0MainWindow@@QEAA@PEAVQWidget@@@Z)
    


  • Ok, I got it worked out. I just needed to use the following:

    main.cpp

    ...some code...
    QPointer<MyQWebEnginePage> thisPage = new MyQWebEnginePage;
    ui->WebEngineView->setPage(thisPage);
    ...some more code...
    

    myqwebenginepage.h

    #ifndef MYQWEBENGINEPAGE_H
    #define MYQWEBENGINEPAGE_H
    
    #include <QWebEnginePage>
    #include <QDesktopServices>
    
    class MyQWebEnginePage : public QWebEnginePage
    {
        Q_OBJECT
    
    public:
        MyQWebEnginePage(QObject* parent = 0) : QWebEnginePage(parent){}
    
        bool acceptNavigationRequest(const QUrl & url, QWebEnginePage::NavigationType type, bool isMainFrame)
        {
            if (type == QWebEnginePage::NavigationTypeLinkClicked)
            {
                QDesktopServices::openUrl(url);
                return false;
            }
            return true;
        }
    };
    
    #endif // MYQWEBENGINEPAGE_H
    

    Thanks for the feedback.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.