QWebEngineView的自定义协议

QWebEngineView是比较新的Qt(这里指6.7.2版本)开发库中自带的Web浏览插件,属于做Qt开发过程中,不可多得的利器。

一般使用

如果在程序中使用QWebEngineView,需要包含它的头文件,连接它的库文件。

它的开发库需要单独安装。

如果是Fedora系统的非开发环境,只需要安装运行所需的库即可。

命令如下:

dnf install qt6-qtwebengine

但如果是开发环境,就不仅要安装运行所需的库,还需要安装开发所需要的库了。

如下:

dnf install qt6-qtwebengine-devel

这个开发包,不仅包含了QWebEngine必要的库,还有相应的pkg-config脚本,以及CMake的脚本。

这样,方便我们在使用CMake构建的项目中直接使用。

比如,可以使用如下命令来给手头的项目增加QWebEngine的支持。

FIND_PACKAGE (Qt6 NAMES Qt6 COMPONENTS WebEngine REQUIRED)
CMAKE_INCLUDE_DIR(${Qt6WebEngine_INCLUDE_DIRS)
ADD_EXECUTE(helloworld helloworld.cc)
TARGET_LINK_LIBRARIES(helloworld Qt6::WebEngine)

之后,就可以在项目中使用WebView来加载网页,相应的方法load,有两种调用方法。

void QWebEngineView::load(const QUrl &url)

void QWebEngineView::load(const QWebEngineHttpRequest &request)

QWebEngineSettings

如果要对QWebEngine的设置进行一些更改,可以使用QWebEngineSettings。

使用QWebEngineView的settings()方法,就可以取得它的实例,之后进行定制。

这个类支持的方法不太多,主要这么几个:

QString 	defaultTextEncoding() const
QString 	fontFamily(QWebEngineSettings::FontFamily which) const
int 	fontSize(QWebEngineSettings::FontSize type) const
void 	resetAttribute(QWebEngineSettings::WebAttribute attribute)
void 	resetFontFamily(QWebEngineSettings::FontFamily which)
void 	resetFontSize(QWebEngineSettings::FontSize type)
void 	resetUnknownUrlSchemePolicy()
void 	setAttribute(QWebEngineSettings::WebAttribute attribute, bool on)
void 	setDefaultTextEncoding(const QString &encoding)
void 	setFontSize(QWebEngineSettings::FontSize type, int size)
void    setUnknownUrlSchemePolicy(QWebEngineSettings::UnknownUrlSchemePolicy policy)
bool 	testAttribute(QWebEngineSettings::WebAttribute attribute) const
QWebEngineSettings::UnknownUrlSchemePolicy 	unknownUrlSchemePolicy() const

如使用如下代码:

auto settings = view->settings ();  
settings->setDefaultTextEncoding ("UTF-8");

就可以指定资源加载时的默认编码。

自定义协议

就像webkit2gtk一样,使用QWebEngine开发,当然也是有自定义协议的需求的。

但是,QWebEngine自定义协议的实现,明显比webkit2gtk要麻烦一些,其中涉及到几个类QWebEngineUrlScheme、QWebEngineUrlSchemeHandler、QWebEngineProfile以及QWebEngineUrlRequestJob。

大体实现方式就是:

  1. 子类化一个QWebEngineUrlSchemeHandler。
  2. 在QApplication初始化之前,先使用QWebEngineUrlScheme注册自己要支持的自定义协议。
  3. 创建一个自定义的QWebEngineUrlSchemeHandler子类,然后把它安装到在QWebEnineView关联的Profile里去。
  4. 在QWebEngineView里去执行load。

QWebEngineUrlSchemeHandler

QWebEngineUrlSchemeHandler是整个自定义协议的实现的核心部分,整个自定义获取资源的过程,都在这个类的requestStarted方法里。

以下是一个简单的样例,代码复制自QWebEngineUrlSchemeHandler的文档

{
public:
    MySchemeHandler(QObject *parent = nullptr);
    void requestStarted(QWebEngineUrlRequestJob *job)
    {
        const QByteArray method = job->requestMethod();
        const QUrl url = job->requestUrl();

        if (isValidUrl(url)) {
            if (method == QByteArrayLiteral("GET")) {
                job->reply(QByteArrayLiteral("text/html"), makeReply(url));
            else // Unsupported method
                job->fail(QWebEngineUrlRequestJob::RequestDenied);
        } else {
            // Invalid URL
            job->fail(QWebEngineUrlRequestJob::UrlNotFound);
        }
    }
    bool isValidUrl(const QUrl &url) const // ....
    QIODevice *makeReply(const QUrl &url) // ....
};

其中,返回给浏览器的地方在job的reply那个方法。

通过官方文档,我们看到这个reply方法有两个参数:

void QWebEngineUrlRequestJob::reply(const QByteArray &contentType, QIODevice *device)

第一个比较容易理解,就是资源的mime类型(样例里写死了是text/html),我们可以灵活使用写成别的。

第二个是Qt里面的一种QIODevice指针。比较麻烦的是,这个指针需要我们根据它的生命周期释放,否则会有内存泄漏。

官方文档给的建议方法是,给job的销毁信号,连接一个槽,来自动释放这个QIODevice。

如:

connect(job, &QObject::destroyed, device, &QObject::deleteLater);

需要注意的是,如果我们的资源有更多需要释放,这个槽的实现就要更全面一些。

QWebEngineUrlScheme

在程序开始的时候,亦即QApplication创建之前,需要把我们向自定义的协议,注册到QWebEngineUrlScheme中去。

如我们要注册一个hello协议,实现如下:

QWebEngineUrlScheme scheme ("hello");  
scheme.setSyntax (QWebEngineUrlScheme::Syntax::Path);    
QWebEngineUrlScheme::registerScheme (scheme);

其中,QWebEngineUrlScheme::Syntax是一个枚举类型,有HostPortAndUserInformation、HostAndPort、Host与Path四种。需要我们根据自己定义的协议,来正确设置这个类型。

QWebEngineProfile

在最终可以使用QWebEngineView的load方法,达到我们的自定义协议的目的之前,还需要把一个QWebEngineUrlSchemeHandler的实例,安装到与我们的QWebEngineView关联的profile上。

比较简单的实现是,安装到默认的QWebEngineProfile上。

如:

auto hanlder = new MySchemeHandler();  
QWebEngineProfile::defaultProfile()->installUrlSchemeHandler (QByteArray ("hello"), handler);

但是如果我们需要更定制化一些,比如每一个不同的QWebEngineView都需要不同的Handler实现,或者不同的实例化参数,就需要如下的方式来安装到特定的profile了。

auto profile = new QWebEngineProfile ();  
auto view = new QWebEngineView (profile);
auto hanlder = new MySchemeHandler();  
QWebEngineProfile::defaultProfile()->installUrlSchemeHandler (QByteArray ("hello"), handler);
  • 23
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值