QT使用QWebEngineView加载显示网页,实现下载功能

文章目录

  • 前言
    • 原文链接
    • 1.QWebEngineViewChw.h
    • 2.QWebEngineViewChw.cpp
    • 3.DecodingCard.h
    • 4.DecodingCard.cpp
    • 5.效果展示
  • 总结


前言

原文链接

提示:以下是本篇文章正文内容,下面案例可供参考

1.QWebEngineViewChw.h

代码如下(示例):

#pragma once

#ifndef QWEBENGINEVIEWCHW_H
#define QWEBENGINEVIEWCHW_H
#include 
#include 
#include "fhelper.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "fMessageDialog.h"
class QWebEngineViewChw : public QWebEngineView
{
	Q_OBJECT
public:
	explicit QWebEngineViewChw(QWidget *parent = nullptr);
	~QWebEngineViewChw()override;

	//文件是否存在
	bool FileIsExist(QString strFile);
Q_SIGNALS:
	void send_X_Y(int x, int y);
protected:
	QWebEngineView* createWindow(QWebEnginePage::WebWindowType type) override;
private slots:
	void slot_LinkHovered(const QString& url);
	void on_webDownload(QWebEngineDownloadItem *item);
	void on_downloadFinished();
	void on_downloadProgress(qint64 CurruntDatalen, qint64 TotalDatalen);
private:
	QUrl	url_;
	QVector<QObject * > mvchildObj;
	QString DownPath;
	QString fileName;
protected:
	bool event(QEvent* evt)override;
	bool eventFilter(QObject *obj, QEvent *ev)override;
};
#endif // QWEBENGINEVIEWCHW_H

2.QWebEngineViewChw.cpp

代码如下(示例):

#include "QwebengineViewchw.h"

#ifdef WIN32  
#pragma execution_character_set("utf-8")
#endif

QWebEngineViewChw::QWebEngineViewChw(QWidget *parent) : QWebEngineView(parent)
{
	setAttribute(Qt::WA_DeleteOnClose);
	connect(this->page(), &QWebEnginePage::linkHovered, this, &QWebEngineViewChw::slot_LinkHovered);
	QWebEngineProfile* webProfile = this->page()->profile();
	connect(webProfile, SIGNAL(downloadRequested(QWebEngineDownloadItem*)), this, SLOT(on_webDownload(QWebEngineDownloadItem*)));
}

QWebEngineViewChw::~QWebEngineViewChw()
{
	
}

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

void QWebEngineViewChw::on_webDownload(QWebEngineDownloadItem *item)
{
	DownPath = item->path();
	connect(item, SIGNAL(finished()), this, SLOT(on_downloadFinished()));
	connect(item, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(on_downloadProgress(qint64, qint64)));
	if (FHelper::nLanguage == 0)
		fileName = QFileDialog::getSaveFileName(this, u8"保存文件", DownPath, QString("Protocol File(.%1)").arg(DownPath.mid(DownPath.lastIndexOf(".") + 1, 10)));
	else if (FHelper::nLanguage == 1)
		fileName = QFileDialog::getSaveFileName(this, u8"Save File", DownPath, QString("Protocol File(.%1)").arg(DownPath.mid(DownPath.lastIndexOf(".") + 1, 10)));
	
	item->setPath(fileName);
	item->accept();
}

void QWebEngineViewChw::on_downloadFinished()
{
	FMessageDialog	dlg;
	if (FileIsExist(fileName))
	{
		if (FHelper::nLanguage == 0)
			dlg.setMsg(FMessageDialog::Information, u8"提示", u8"导出配置完成!");
		else if (FHelper::nLanguage == 1)
			dlg.setMsg(FMessageDialog::Information, u8"Tip", u8"Export configuration completed!");
	}
	else
	{
		if (FHelper::nLanguage == 0)
			dlg.setMsg(FMessageDialog::Error, u8"提示", u8"导出配置失败!");
		else if (FHelper::nLanguage == 1)
			dlg.setMsg(FMessageDialog::Error, u8"Tip", u8"Export configuration failed!");
	}
	dlg.exec();
}

void QWebEngineViewChw::on_downloadProgress(qint64 CurruntDatalen, qint64 TotalDatalen)
{
	qDebug() << "CurruntDatalen = " << CurruntDatalen << "TotalDatalen = " << TotalDatalen;
}

void QWebEngineViewChw::slot_LinkHovered(const QString &url)
{
	//获取视图里面点击的链接地址
    //qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" "<
	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;
				emit send_X_Y(x, y);
				return QWebEngineView::eventFilter(obj, ev);
			}
		}
	}
	return QWebEngineView::eventFilter(obj, ev);
}

//文件是否存在
bool QWebEngineViewChw::FileIsExist(QString strFile)
{
	QFile tempFile(strFile);
	return tempFile.exists();
}

3.DecodingCard.h

代码如下(示例):

#pragma once
#include "fBaseDialog.h"
#include "titlebar.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include "QwebengineViewchw.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

class DecodingCard : public FBaseDialog
{
	Q_OBJECT

public:
	DecodingCard(QWidget *parent = Q_NULLPTR);
	~DecodingCard();

	void SendKeyString(const char *str);

public Q_SLOTS:
	void get_X_Y(int x, int y);
	void getDecodingCardIP(QString nCardIp);

private slots:
	void slot_LinkHovered(const QString& url);

private:
	void initData();
	void closeEvent(QCloseEvent *event);
private:
	QWebEngineViewChw *m_webView;
	QUrl url_;
	TitleBar *DecodingCardTitleBar;
};

4.DecodingCard.cpp

代码如下(示例):

#include "DecodingCard.h"

#pragma execution_character_set("utf-8")

DecodingCard::DecodingCard(QWidget *parent)
	: FBaseDialog(parent)
{
	initData();
}

DecodingCard::~DecodingCard()
{

}

void DecodingCard::initData()
{
	FBaseDialog::IsSetFixedSize(1);
	showSize = QSize(1200, 700);
	setTitle(tr("解码卡"));
}

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

void DecodingCard::get_X_Y(int x, int y)
{
	qDebug() << "[" << __FILE__ << "]" << __LINE__ << __FUNCTION__ << "x = " << "y = " << y;
	if (x >= this->width() - 80 && x <= this->width() && y >= 0 && y <= 50)
	{
		m_webView->reload();
		this->close();
	}
}

void DecodingCard::SendKeyString(const char *str) {
	DWORD sc, shift;
	unsigned char vkey;
	int i;
	for (i = 0; str[i] != '\0'; i++) {
		sc = OemKeyScan(str[i]);
		shift = sc >> 16;
		vkey = MapVirtualKey(sc & 0xffff, 1);
		if (shift)
			keybd_event(VK_SHIFT, 0, 0, 0);

		keybd_event(vkey, 0, 0, 0);
		keybd_event(vkey, 0, KEYEVENTF_KEYUP, 0);
		if (shift)
			keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
	}
}

void DecodingCard::getDecodingCardIP(QString nCardIp)
{
	qDebug() << "61---nCardIp = " << nCardIp;
	//导入网页显示
	m_webView = new QWebEngineViewChw(this);
	connect(m_webView, &QWebEngineViewChw::send_X_Y, this, &DecodingCard::get_X_Y);
	QStackedLayout* layout = new QStackedLayout;
	setLayout(layout);
	layout->addWidget(m_webView);
	m_webView->load(QUrl(nCardIp));
	connect(m_webView->page(), &QWebEnginePage::linkHovered, this, &DecodingCard::slot_LinkHovered);

	//自动登录账号
	//[1]使用Qt自带函数,只能发送在软件内部控件
	QTimer::singleShot(1000, this, [=]() {
		QWidget* obj = QApplication::focusWidget();
		if (nullptr != obj)  // 要注意判空,否则会崩溃     
		{
			QString bytes = "admin";
			for (int i = 0; i < bytes.length(); i++)
			{
				QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, QString(bytes.at(i)));//输入账号            
				QApplication::sendEvent(obj, &keyPress);
			}
			QKeyEvent keyTab(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);//tab 
			QApplication::sendEvent(obj, &keyTab);
			for (int i = 0; i < bytes.length(); i++)
			{
				QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, QString(bytes.at(i)));//输入密码         
				QApplication::sendEvent(obj, &keyPress);
			}
			QKeyEvent keyEnter(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier);//回车确认登录                            
			QApplication::sendEvent(obj, &keyEnter);
		}
		});
	//[2]使用windows自带函数,发送全局键盘事件
	/*QTimer::singleShot(1000, this, [=]() {
		const char *text = "admin";
		SendKeyString(text);
		keybd_event(VK_TAB, 0, 0, 0);
		SendKeyString(text);
		keybd_event(VK_RETURN, 0, 0, 0);
	});*/
}

void DecodingCard::closeEvent(QCloseEvent *event)
{
	m_webView->reload();
	this->close();
	QDialog::closeEvent(event);
}


5.效果展示


总结

刚好需要用到自己嵌入一个浏览器,在网上找了一些资料,刚好可以满足需求,记录一下以后用

你可能感兴趣的:(qt,开发语言)