Qwebview浏览器

一、支持功能

1.1、加载网页,加载本地html文件(暂不支持js交互)
1.2、点击页面跳转
1.3、F5刷新、F12调试器
1.4、ctrl+滚轮滑动改变页面大小
1.5、滚轮滑动页面联动
1.6、js和C++互相调用(页面放大/缩小显示放大比例)

二、源代码

main.cpp

#include <iostream>
#include <QApplication>
#include "WebviewImpl.h"
#include "Path.h"


int main(int argc, char* argv[])
{
    QApplication a(argc, argv);

    WebviewImpl view;
    {
        // local file, prefix: file:/ + source
        std::string strSourcePath = "file:/" + Utils::GetSourcePath() + "js_test/html/test.html";
        //view.load(QUrl("https://www.qt.io/"));
        //view.load(QUrl(strSourcePath.c_str()));
        view.load(QUrl("http://www.baidu.com"));
        view.show();
    }

    int nCode = a.exec();

    // do something(uninit)

    return nCode;
}

Path.h

#pragma once
#include <string>
#include <direct.h>
#include <fstream>


namespace Utils
{
    const int kMaxPath = 260;
    static std::string GetSourcePath()
    {
        char szPath[kMaxPath] = { 0 };
        _getcwd(szPath, kMaxPath);
        std::string strSourcePath(szPath);
        if(strSourcePath.back() != '\\' || strSourcePath.back() != '\/')
            strSourcePath += "/";
        return strSourcePath;
    }

    static bool IsFileExist(const std::string& strFile)
    {
        bool bExist = false;
        std::fstream fin(strFile, std::ios::in);
        if(fin.is_open())
        {
            bExist =true;
            fin.close();
        }
        return bExist;
    }
}

WebviewImpl.h

#pragma once
#include <QWebView>
#include <QKeyEvent>

class QWebInspector;
class WebviewImpl : public QWebView
{
    Q_OBJECT
public:
    WebviewImpl();
    ~WebviewImpl();
    void CallJs(const QString& qstrInfo);

protected:
    QWebView* createWindow(QWebPage::WebWindowType type) override;
    void keyPressEvent(QKeyEvent*) override;
    void keyReleaseEvent(QKeyEvent*) override;
    void wheelEvent(QWheelEvent*) override;

private slots:
    void onLoadFinished(bool bFinished);
    void onLoadProgress(int nProgress);
    void onTitleChanged(const QString& qstrTitle);
    void onIconChanged();
    void onUrlChanged(const QUrl&);
    void onLoadUrl(const QUrl&);

private:
    void init_signals();

private:
    QWebInspector* m_pInspector;
    bool m_bCtrlPressed;

};




WebviewImpl.cpp

#include "WebviewImpl.h"
#include <QDebug>
#include <QWebInspector>
#include <QWebFrame>
#include "JsHelper.h"



WebviewImpl::WebviewImpl()
    : QWebView(nullptr)
    , m_pInspector(nullptr)
    , m_bCtrlPressed(false)
{
    init_signals();
    // close window will invoke destruct function, it'll crash while support debugger
    //setAttribute(Qt::WA_DeleteOnClose);
    setAttribute(Qt::WA_TranslucentBackground);
    //setWindowFlags(Qt::FramelessWindowHint);// | Qt::WindowStaysOnTopHint);
    QWebSettings* settings = this->settings();
    //settings->setAttribute(QWebSettings::PluginsEnabled, true);
    settings->setAttribute(QWebSettings::JavaEnabled, true);
    settings->setAttribute(QWebSettings::JavascriptEnabled, true);
    //settings->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
    //settings->setAttribute(QWebSettings::JavascriptCanAccessClipboard, true);

    // debugger window(F12)
    settings->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
    //settings->setAttribute(QWebSettings::SpatialNavigationEnabled, true);
    //settings->setAttribute(QWebSettings::LinksIncludedInFocusChain, true);
    //settings->setAttribute(QWebSettings::AcceleratedCompositingEnabled, true);
    //settings->setAttribute(QWebSettings::AutoLoadImages, true);
    setContextMenuPolicy(Qt::NoContextMenu);    // disable menu with mouse right click
}

WebviewImpl::~WebviewImpl()
{
    if (m_pInspector != nullptr)
    {
        delete m_pInspector;
        m_pInspector = nullptr;
    }
}

void WebviewImpl::CallJs(const QString& qstrInfo)
{
    page()->mainFrame()->evaluateJavaScript(qstrInfo);
}

/***************************************************************************************************
*                                           override                                               *
****************************************************************************************************/
QWebView* WebviewImpl::createWindow(QWebPage::WebWindowType type)
{
    // create a new webview for click
    WebviewImpl* pView = new WebviewImpl();
    connect(pView, SIGNAL(urlChanged(const QUrl&)), this, SLOT(onLoadUrl(const QUrl&)));
    return pView;
}

void WebviewImpl::keyPressEvent(QKeyEvent* pEvent)
{
    switch (pEvent->key())
    {
    case Qt::Key_F5:    // F5
    {
        this->reload();
        break;
    }
    case Qt::Key_F12:   // F12
    {
        if (nullptr == m_pInspector)
        {
            m_pInspector = new QWebInspector(/*this*/);
            m_pInspector->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog);
            m_pInspector->setMinimumSize(500, 300);
            m_pInspector->setPage(this->page());
            //m_pInspector->setAttribute(Qt::WA_DeleteOnClose);
        }
        m_pInspector->show();
        qDebug() << "F12 pressed";
        break;
    }
    case Qt::Key_Control:   // ctrl pressed
    {
        m_bCtrlPressed = true;
        break;
    }
    default:
        break;
    }
    QWebView::keyPressEvent(pEvent);
}

void WebviewImpl::keyReleaseEvent(QKeyEvent* pEvent)
{
    switch (pEvent->key())
    {
    case Qt::Key_Control:   // ctrl released
    {
        m_bCtrlPressed = false;
        break;
    }
    default:
        break;
    }
    QWebView::keyReleaseEvent(pEvent);
}

void WebviewImpl::wheelEvent(QWheelEvent* pEvent)
{
    int nDelta = pEvent->delta();
    if (m_bCtrlPressed)
    {
        // ctrl + wheel
        if (nDelta > 0)    // up
        {
            this->setZoomFactor(this->zoomFactor() + 0.1);
        }
        else
        {
            this->setZoomFactor(this->zoomFactor() - 0.1);
        }
        QString qstrInfo = QString("UpdateInfo('Factor %1%')").arg(this->zoomFactor() * 100);
        CallJs(qstrInfo);
    }
    else
    {
        QPoint ptScroll = this->page()->mainFrame()->scrollPosition();
        if (ptScroll.y() < 0) return;  // filter the invalid value
        // handle wheel for view
        ptScroll.setY(ptScroll.y() - nDelta);
        this->page()->mainFrame()->setScrollPosition(ptScroll);
    }
    QWebView::wheelEvent(pEvent);
}

/***************************************************************************************************
*                                           slots                                                  *
****************************************************************************************************/
void WebviewImpl::onLoadFinished(bool bFinished)
{
    qDebug() << "Load state: " << bFinished;
    if (bFinished)
    {
        this->page();
        this->setWindowIcon(this->icon());
        // js interactive
        this->page()->mainFrame()->addToJavaScriptWindowObject("view", &JsHelper::Instance());
        QWebSettings::clearMemoryCaches();
        QWebSettings::clearIconDatabase();
    }
}

void WebviewImpl::onLoadProgress(int nProgress)
{
    //qDebug() << "Load progress: " << nProgress;
}

void WebviewImpl::onTitleChanged(const QString& qstrTitle)
{
    if (qstrTitle.isEmpty()) return;
    qDebug() << "Title changed: " << qstrTitle;
    this->setWindowTitle(qstrTitle);
}

void WebviewImpl::onIconChanged()
{
    // don't invoke forever, genius
    qDebug() << "Ico changed: ";
}

void WebviewImpl::onUrlChanged(const QUrl& url)
{
    qDebug() << "Url changed: " << url;
}

void WebviewImpl::onLoadUrl(const QUrl& url)
{
    load(url);
}

/***************************************************************************************************
*                                           private funciton                                       *
****************************************************************************************************/
void WebviewImpl::init_signals()
{
    bool bSucc = false;
    connect(this, SIGNAL(loadFinished(bool)), this, SLOT(onLoadFinished(bool)));
    connect(this, SIGNAL(loadProgress(int)), this, SLOT(onLoadProgress(int)));
    connect(this, SIGNAL(urlChanged(const QUrl&)), this, SLOT(onUrlChanged(const QUrl&)));
    connect(this, SIGNAL(titleChanged(const QString&)), this, SLOT(onTitleChanged(const QString&)));
    bSucc = connect(this, SIGNAL(iconChanged()), this, SLOT(onIconChanged()));
    //connect(page()->mainFrame(), SIGNAL(loadFinished(bool)), SLOT(onLoadFinished(bool)));

    //qDebug() << "Connect state: " << bSucc;
}


JsHelper.h

#pragma once
#include <QObject>
#include "Singleton.h"

class JsHelper : public QObject, public Singleton<JsHelper>
{
    friend class Singleton<JsHelper>;
    Q_OBJECT

public:
    JsHelper(QWidget* parent = nullptr);
    ~JsHelper();
    

public slots:
    // js invoke, it must public slots
    void onShowJsInfo(const QString& qstrInfo);;

};

JsHelper.cpp

#include "JsHelper.h"
#include <QDebug>




JsHelper::JsHelper(QWidget* parent/* = nullptr*/)
{

}

JsHelper::~JsHelper()
{

}

/***************************************************************************************************
*                                           js functions                                           *
****************************************************************************************************/
void JsHelper::onShowJsInfo(const QString& qstrInfo)
{
    qDebug() << "JS called, info: " << qstrInfo;
}

test.html

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>JavaScript 调用 C++ 函数</title>

    <script>
        function CallCppFunc() {
            var info = document.getElementById("txtInfo").value;
            if (info == "") {
                alert("请输入要发送给 C++ 的数据!");
                return;
            }
            view.onShowJsInfo(info);
        }
		function UpdateInfo(info) {
			//alert("invoke");
			var show_info = document.getElementById("txtInfo");
			show_info.value=info;
        }
    </script>
</head>
<body>
    <input id="txtInfo" type="text" />
    <button id="btnCallCppFunc" onclick="CallCppFunc();">调用 C++ 函数</button>
</body>
</html>

三、扫坑

QSslSocket: cannot call unresolved function
Solve:***将系统的ssleay32.dll和ssleay32.dll到qt的bin目录***
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值