参考:https://blog.csdn.net/weixin_40355471/article/details/120698537
QT实现浏览器访问网页,使用QWebEngineView
需要添加QT += webenginewidgets
源代码:
重写QWebEngineView类
头文件:
#pragma once
#include <QObject>
#include <QWidget>
#include <QWebEngineView>
#include <qwebenginepage.h>
#include <qurl.h>
#include <QMouseEvent>
#include <QApplication>
/*
解决两个问题:
1.QWebEngineView不支持点击超链接自动跳转,对createWindow处理后可支持跳转;
2、QWebEngineView浏览web时鼠标事件被本身的child接收了,因此浏览网页时获取不了
qt的鼠标事件,这里通过QEvent::ChildPolished安装事件过滤器的方式获取鼠标事件。
*/
class QWebEngineViewRewrite : public QWebEngineView
{
Q_OBJECT
public:
QWebEngineViewRewrite(QWidget *parent = nullptr);
~QWebEngineViewRewrite();
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;
};
源文件:
#include "QWebEngineViewRewrite.h"
QWebEngineViewRewrite::QWebEngineViewRewrite(QWidget* parent)
: QWebEngineView(parent)
{
setAttribute(Qt::WA_DeleteOnClose);
connect(this->page(), &QWebEnginePage::linkHovered, this, &QWebEngineViewRewrite::slot_LinkHovered);
}
QWebEngineViewRewrite::~QWebEngineViewRewrite()
{
}
QWebEngineView* QWebEngineViewRewrite::createWindow(QWebEnginePage::WebWindowType type)
{
//加载链接地址
if (!url_.isEmpty())
{
this->load(url_);
emit QEvent::ChildPolished;//重新加载页面时,手动触发一个ChildPolished事件
}
return nullptr;
}
void QWebEngineViewRewrite::slot_LinkHovered(const QString& url)
{
// 获取视图里面点击的链接地址
// qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" "<<url;
url_.setUrl(url);
}
bool QWebEngineViewRewrite::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 QWebEngineViewRewrite::eventFilter(QObject* _obj, QEvent* _event)
{
foreach(QObject * childObj, mvchildObj)
{
if (_obj == childObj)
{
if (/*obj == childObj&& */(_event->type() == QEvent::MouseButtonPress || _event->type() == QEvent::MouseButtonDblClick))
{
QMouseEvent* MouseEvent = static_cast<QMouseEvent*>(_event);
int x = MouseEvent->x();
int y = MouseEvent->y();
qDebug() << "[" << __FILE__ << "]" << __LINE__ << __FUNCTION__ << " " << x << y;
return QWebEngineView::eventFilter(_obj, _event);
}
}
}
return QWebEngineView::eventFilter(_obj, _event);
}
实现类头文件:
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_WebWidget.h"
#include <QWebEngineView>
#include "QWebEngineViewRewrite.h"
class WebWidget : public QMainWindow
{
Q_OBJECT
public:
WebWidget(QWidget *parent = Q_NULLPTR);
private slots:
void on_pushButton_clicked(); // 访问
void on_pushButton_2_clicked(); // 刷新
void on_pushButton_back_clicked(); // 后退
void on_pushButton_forward_clicked(); // 前进
private:
Ui::WebWidgetClass ui;
QNetworkAccessManager* manager;
QWebEngineView* m_webView;
};
实现类源文件:
#include "WebWidget.h"
#include <QNetworkProxyFactory>
WebWidget::WebWidget(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
this->setWindowTitle(QStringLiteral("QWebEngineView浏览器"));
QNetworkProxyFactory::setUseSystemConfiguration(false);
m_webView = new QWebEngineViewRewrite(this);
ui.verticalLayout->addWidget(m_webView);
m_webView->load(QString("https://blog.csdn.net/weixin_40355471/article/details/120698537"));
}
//访问
void WebWidget::on_pushButton_clicked()
{
QString url = ui.lineEdit->text();
if (!url.isEmpty())
{
m_webView->load(url);
}
}
//刷新
void WebWidget::on_pushButton_2_clicked()
{
m_webView->reload();
}
//后退
void WebWidget::on_pushButton_back_clicked()
{
m_webView->back();
}
//前进
void WebWidget::on_pushButton_forward_clicked()
{
m_webView->forward();
}