QT实现浏览器访问网页,使用QWebEngineView

2023-05-16

支持访问网页,前进、后退、刷新,点击超链接自动跳转,获取网页鼠标事件,重新编译QWebEngineView库后还可以支持播放mp4等视频;
Qt在debug模式运行有时访问网页很卡,切换release版后访问速度基本正常。

目录

  • 环境说明
  • 源代码
  • 效果图
  • QWebEngineView缺点和优点

环境说明

使用QWebEngineView类实现,qt5.6及以上版本;
qt安装时需要勾选:Qt WebEngine;
由于chrome不支持mingw编译,构建套件只能选择vs的编译器;
pro工程文件添加QT += webenginewidgets

源代码

重写QWebEngineView类,主要实现两个功能:
1、QWebEngineView不支持点击超链接自动跳转,对createWindow处理后可支持跳转;
2、QWebEngineView浏览web时鼠标事件被本身的child接收了,因此浏览网页时获取不了qt的鼠标事件,这里通过QEvent::ChildPolished安装事件过滤器的方式获取鼠标事件。

qwebengineviewchw.h

#ifndef QWEBENGINEVIEWCHW_H
#define QWEBENGINEVIEWCHW_H
#include <QWidget>
#include <QWebEngineView>
#include <qwebenginepage.h>
#include <qurl.h>
#include <QMouseEvent>
#include <QApplication>
class QWebEngineViewChw : public QWebEngineView
{
    Q_OBJECT
public:
    explicit QWebEngineViewChw(QWidget *parent = nullptr);
    ~QWebEngineViewChw()override;
protected:
    QWebEngineView* createWindow(QWebEnginePage::WebWindowType type) override;
private slots:
    void slot_LinkHovered(const QString& url);
private:
    QUrl	url_;
    QVector<QObject * > mvchildObj;
protected:
    bool event(QEvent* evt)override;

    bool eventFilter(QObject *obj, QEvent *ev)override;
};
#endif // QWEBENGINEVIEWCHW_H

qwebengineviewchw.cpp

#include "qwebengineviewchw.h"
QWebEngineViewChw::QWebEngineViewChw(QWidget *parent) : QWebEngineView(parent)
{
    setAttribute(Qt::WA_DeleteOnClose);

    connect(this->page(), &QWebEnginePage::linkHovered, this, &QWebEngineViewChw::slot_LinkHovered);
}

QWebEngineViewChw::~QWebEngineViewChw()
{
}

QWebEngineView *QWebEngineViewChw::createWindow(QWebEnginePage::WebWindowType type)
{
    //加载链接地址
    if(!url_.isEmpty())
    {
        this->load(url_);
        emit QEvent::ChildPolished;//重新加载页面时,手动触发一个ChildPolished事件
    }
//    return this;
    return nullptr;
}

void QWebEngineViewChw::slot_LinkHovered(const QString &url)
{
    //获取视图里面点击的链接地址
//    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" "<<url;
    url_.setUrl(url);
}

bool QWebEngineViewChw::event(QEvent *evt)
{
    //每次新加载URL时手动触发该事件,生成一个QChildEvent
    if (evt->type() == QEvent::ChildPolished)
    {
        qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" ";
        QChildEvent *child_ev = static_cast<QChildEvent*>(evt);

        QObject *childObj = child_ev->child();
        mvchildObj.append(childObj);
        if (childObj)
        {
            childObj->installEventFilter(this);
        }
    }

    return QWebEngineView::event(evt);
}

bool QWebEngineViewChw::eventFilter(QObject *obj, QEvent *ev)
{
    foreach(QObject *childObj,mvchildObj)
    {
        if (obj == childObj)
        {
            if (/*obj == childObj&& */(ev->type() == QEvent::MouseButtonPress|| ev->type() == QEvent::MouseButtonDblClick))
            {
                QMouseEvent *MouseEvent = static_cast<QMouseEvent *>(ev);
                int x = MouseEvent->x();
                int y = MouseEvent->y();
                qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" "<<x <<y;
                return QWebEngineView::eventFilter(obj, ev);
            }
        }
    }
    return QWebEngineView::eventFilter(obj, ev);
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QWebEngineView>
#include "qwebengineviewchw.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private slots:
    void on_pushButton_clicked();//访问
    void on_pushButton_2_clicked();//刷新
    void on_pushButton_back_clicked();//后退
    void on_pushButton_forward_clicked();//前进
private:
    Ui::MainWindow *ui;
    QWebEngineViewChw *m_webView;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkProxyFactory>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowTitle(QStringLiteral("QWebEngineView浏览器"));
//    qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "7777");
    QNetworkProxyFactory::setUseSystemConfiguration(false);

    m_webView = new QWebEngineViewChw(this);
    ui->verticalLayout->addWidget(m_webView);
}

MainWindow::~MainWindow()
{
    delete ui;
}
//访问
void MainWindow::on_pushButton_clicked()
{
    QString url = ui->lineEdit->text();
    if (!url.isEmpty())
    {
        m_webView->load(url);
    }
}
//刷新
void MainWindow::on_pushButton_2_clicked()
{
    m_webView->reload();
}
//后退
void MainWindow::on_pushButton_back_clicked()
{
    m_webView->back();
}
//前进
void MainWindow::on_pushButton_forward_clicked()
{
    m_webView->forward();
}

效果图

在这里插入图片描述

QWebEngineView缺点和优点

1、由于QWebEngineView没有视频解码器,无法播放mp4等视频,需要重新编译QWebEngineView库,编译过程比较复杂不建议自己尝试,可以在网上下载别人编译好的,编译库和使用库的qt版本、vs版本、位数等要保持一致;

2、点击链接不跳转,重写QWebEngineView类,自动识别鼠标放在链接上面的URL地址,但有些网页链接鼠标放上不显示URL地址,这种情况无法跳转,存在一定BUG;

总结一下:简单的浏览器可以使用QWebEngineView,比较容易实现,但是稳定性和兼容性差一些,后续会研究CEF(Chromium嵌入式框架) ,并嵌入到qt程序实现浏览器功能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT实现浏览器访问网页,使用QWebEngineView 的相关文章

随机推荐

  • 浅谈STM32串口通信(一)基本介绍和一个字节传输的实现

    文章目录 0 传输引脚1 传输一个字节1 1 发送一个字节1 2 接收一个字节 2 代码2 1 配置2 2 发送一个字节2 3 接收一个字节 0 传输引脚 串口收发共需要三根线 其中 TX脚为发送引脚 RX脚为发送引脚 GND为地 作为电平
  • 图像融合(Image Fusion)简介

    图像融合 Image Fusion 是用特定的算法将两幅或多幅图像综合成一幅新的图像 融合结果由于能利用两幅 或多幅 图像在时空上的相关性及信息上的互补性 xff0c 并使得融合后得到的图像对场景有更全面 清晰的描述 xff0c 从而更有利
  • IP地址分类

    大家好呀 xff0c 我是请假君 xff0c 今天又来和大家一起学习数通了 xff0c 今天要分享的知识是IP地址的分类 各个网段内具有的IP节点数各不相同 xff0c 为了适应这种需求 xff0c IP地址被分成五类 1 A类IP地址的第
  • 解决映射网络驱动器自动断开问题

    解决映射网络驱动器自动断开问题 hzq0201 2012 04 13 06 47 36 2777 收藏 2 版权 映射的网络驱动器在一段时间自动断开 xff0c 是由于服务器服务自动断开连接功能的默认超时期限造成的 xff0c 我们可以通过
  • vector深度探索

    声明 xff1a 本文中所有图件都来自B站侯捷老师授课视频 vecctor 底层实现原理 图1 GNU2 9 实现的容器vector vector 的内存是动态增长的 xff0c vector 最重要的三个成员变量为 三个迭代器 xff1a
  • 发送一个http请求以及url三部分组成和语法

    浏览器从URL中解析出服务器的主机名浏览器讲服务器的主机名转化成服务器的IP地址 xff08 DNS解析 xff09 浏览器将端口号从URL解析出来浏览器建立一条鱼web服务器的TCP连接浏览器向服务器发送一条http请求报文服务器向浏览器
  • 结构体对齐规则

    结构体 xff1a 结构体 xff08 struct xff09 是由一系列具有相同类型或不同类型的数据构成的集合 因为这一特性 xff0c 方便了开发者在使用的过程中可以将需要的不同的数据类型放在一起 xff0c 做成我们需要的数据类型
  • GPS坐标用于机器人定位的简单处理

    文章目录 前言一 GPS数据格式二 GPS坐标转换二维坐标原理三 参考代码1 转换经纬度格式2 解析通过串口获得的NMEA数据3 将经纬度转换为xy平面二维坐标 前言 最近工作上面接触使用GPS的NMEA数据为机器人提供平面坐标定位 xff
  • 学完C++基础后再学什么?

    学完 xff1f 那是什么程度 xff1f STL用得熟练吗 xff1f 算法和数据结构掌握得怎么样呢 xff1f 会写界面吗 xff1f BOOST呢 xff1f 像楼上所说的换一种语言 xff0c 简直是痴人说梦 xff0c 如果不深入
  • 视觉SLAM十四讲:回环检测-知识点+代码

    目录 基于外观的几何关系1 基础知识1 1 准确率和召回率1 2 词袋模型1 3 字典1 4 字典的数据结构1 5 相似度的计算1 6 相似度评分的处理1 7 检测回环后的验证 2 实践与代码解析2 1 创建字典2 2 相似度计算 回环检测
  • QT笔记--QT内类的层次关系,以及控件从属关系

    QT窗口界面使用的类层次如下 只包含了直接使用部分 界面上每一个创建的控件 xff0c 都是一个控件类的对象 xff0c 定义在头文件ui mainwindoow h的类UI MainWindow中 xff0c 并且其中的成员函数setup
  • C_带参数的宏定义

    C 带参数的宏定义 xff23 语言允许宏带有参数 在宏定义中的参数称为形式参数 xff0c 在宏调用中的参数称为实际参数 对带参数的宏 xff0c 在调用中 xff0c 不仅要宏展开 xff0c 而且要用实参去代换形参 带参宏定义的一般形
  • 十进制数转换成十六进制数~C语言

    include lt stdio h gt 下面将整数a转换成十六进制输出的字符串 原理 xff1a 1 xff0c 首先知道0b100000 61 0b10000 2 61 0b1000 2 61 0b100 2 61 0b10 2 利用
  • Qt实现线程安全的单例模式

    实现方式 1 实现单例 把类的构造函数 拷贝构造函数 赋值操作符定义为private的 xff1b 把获取单例的接口和唯一的实例指针定义为static的 xff0c 不需要实例化 xff0c 直接通过类名即可访问 2 支持多线程 采用双重校
  • 文本文件和二进制文件的差异和区别

    广义上的二进制文件包括文本文件 xff0c 这里讨论的是狭义上的二进制文件与文本文件的比较 xff1a 能存储的数据类型不同 文本文件只能存储char型字符变量 二进制文件可以存储char int short long float 各种变量
  • Qt实现记录日志文件log

    概述 Qt有两种实现记录日志的方式 xff0c 第一种是安装自定义的Qt消息处理程序 xff0c 自动输出程序产生的调试消息 警告 关键和致命错误消息的函数 xff1b 第二种是自定义一个类 xff0c 可以在程序指定位置打印输出指定的内容
  • Qt在linux环境下调用动态库,pro工程文件加载库和QLibrary加载库两种方式

    QT调用动态库 xff0c 在编译时和运行时的方式不同 xff0c 编译时可在pro文件加载或使用QLibrary类加载 xff1b 运行时依赖环境变量 xff0c windows下直接把动态库拷贝到可执行文件目录即可 xff0c linu
  • linux下QT发布程序双击打不开解决方法

    现象 Qt开发的程序 xff0c 使用 终端可以打开 xff0c 双击却打不开 阶段一 右键可执行程序 xff0c 选择属性 xff0c 可执行程序类型如果是 application x sharedlib xff0c 在QT的pro文件添
  • Qt发起http请求,get和post方式,并接收响应数据

    目录 Qt发起http请求get xff0c 异步接收Qt发起http请求post xff0c 异步接收Qt发起http请求get和post xff0c 收发同步http下载网络图片 Qt发起http请求get xff0c 异步接收 get
  • QT实现浏览器访问网页,使用QWebEngineView

    支持访问网页 xff0c 前进 后退 刷新 xff0c 点击超链接自动跳转 xff0c 获取网页鼠标事件 xff0c 重新编译QWebEngineView库后还可以支持播放mp4等视频 xff1b Qt在debug模式运行有时访问网页很卡