当前位置: 首页 > article >正文

Qt调用Chrome浏览器

一、前言

最近有个小项目需要跳转网页,之前有了解过,但是没有在项目中使用过Qt网页嵌入;

结合自己之前的博客,有如下两种技术可以实现我的需求:

1、Qt–网页嵌入

2、Qt使用QAxWidget调用Windows组件

但是在实际开发中发现:

  • 技术一:使用QWebEngineView来展示网页,卡顿,界面还有时闪退,不知如何解决;
  • 技术二:使用QAxWidget调用Windows组件,就是调用IE浏览器,发现IE浏览器太老,老是弹出脚本页面错误;

然后就想到了调用Chrome浏览器的方案!


二、调用Chrome步骤

问题描述:利用chrome谷歌浏览器打开多个网页(多个窗口显示),分别获取每个窗口的句柄,并能对各个窗口设置大小和位置;

  • 打开多个窗口 用 --new-window
  • 获取打开网页(一个网页一个窗口)的窗口句柄,浏览器并不像应用程序一样只有一个进程,打开一个chrome谷歌浏览器默认会有一个主进程和多个子进程,关键是要找到自己打开的那个网页的进程。所有我只能通过标签的名字来想办法了。因为这些子进程的类名都是“Chrome_WidgetWin_1”,根本无法分辨。

2.1、用进程QProcess打开chrome谷歌浏览器

QString appUrl ="C:/Users/wangjichuan/AppData/Local/Google/Chrome/Application/chrome.exe";
QFile file_Chrome(appUrl);
if(!file_Chrome.exists()){
	qDebug()<<"Chrome.exe 路径错误";
    return;
}

QStringList arguments;
arguments <<" --new-window"<<"www.baidu.com";

QProcess* chrome_Process = new QProcess();
chrome_Process->start(appUrl,arguments);
chrome_Process->waitForFinished(1000);

2.2、获取刚才打开的百度网页的窗口句柄

PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
BOOL find = Process32First(hp, &pe32);
QList<HWND> hwndList;
while (find) {
	find = Process32Next(hp, &pe32);
    QString str1 = QString::fromWCharArray(pe32.szExeFile);
    if(str1=="chrome.exe") {
         DWORD jinchengid = pe32.th32ProcessID;
         hwndList = GetWindowHandleByPIDq(jinchengid);
         break;
    }
}

if(hwndList.size() == 1) {
	m_HWND_list.append(hwndList.at(0));
    QWindow *pWin = QWindow::fromWinId((WId)hwndList.at(0));//根据句柄获得该窗口
    pWin->setGeometry(0,0,1920,1080);//对窗口设置位置和大小
}

函数: GetWindowHandleByPIDq

QList<HWND> Widget::GetWindowHandleByPIDq(DWORD dwProcessID)//通过进程ID获取子窗口
{
    QList<HWND> HWND_list;
    HWND h = ::GetTopWindow(0);
    while (h)
    {
        DWORD pid = 0;
        DWORD dwTheardId = GetWindowThreadProcessId(h, &pid);

        if (dwTheardId != 0) {
            if(pid==dwProcessID) {
                TCHAR *name=new TCHAR[MAX_PATH];
                //::GetClassName(h, name, 255);
                ::GetWindowTextW(h, name, 255);
                QString title = QString :: fromStdWString(name);
                if(title.contains("- Google Chrome")&&title!="任务管理器 - Google Chrome") {   //自己打开的窗口都是以- Google Chrom结尾
                    HWND_list.append(h);  //HWND_list记录所有谷歌浏览器下打开的窗口
                    if(m_HWND_list.contains(h)) {   //m_HWND_list存的是之前已经打开并记录下来的窗口  m_HWND_list需自己在头文件定义一下 QList<HWND> m_HWND_list;
                        HWND_list.removeOne(h);//只记录现在打开的窗口
                    }
                }
            }
        }
        h = ::GetNextWindow(h, GW_HWNDNEXT);
    }

    return HWND_list;//返回的最新打开的窗口(就一个)
}

三、相关代码

头文件

#include <QWindow>
#include <windows.h>
#include <TlHelp32.h>
#include <QProcess>

class Widget : public QWidget
{
    Q_OBJECT

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

public:
	QList<HWND> m_HWND_list;
	QList<HWND> GetWindowHandleByPIDq(DWORD dwProcessID);

	QProcess* chrome_Process{nullptr};
	void startChrome(QString web);
	void closeChrome();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

源文件

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    
    closeChrome();
    startChrome("www.baidu.com");
  	
}
Widget::~Widget()
{
    delete ui;
}

//============================================================================================
void Widget::startChrome(QString web)
{
    //浏览器窗口
    //1、用进程QProcess打开chrome谷歌浏览器
    QString appUrl ="C:/Users/wangjichuan/AppData/Local/Google/Chrome/Application/chrome.exe";
	QFile file_Chrome(appUrl);
	if(!file_Chrome.exists()){
		qDebug()<<"Chrome.exe 路径错误";
    	return;
	}

	QStringList arguments;
	arguments <<" --new-window"<<"www.baidu.com";

	chrome_Process = new QProcess();
	chrome_Process->start(appUrl,arguments);
	chrome_Process->waitForFinished(1000);

    //2、获取刚才打开的百度网页的窗口句柄
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(pe32);
    HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    BOOL find = Process32First(hp, &pe32);
    QList<HWND> hwndList;
    while (find) {
    	find = Process32Next(hp, &pe32);
        QString str1 = QString::fromWCharArray(pe32.szExeFile);
        if(str1=="chrome.exe") {
        	DWORD jinchengid = pe32.th32ProcessID;
            hwndList = GetWindowHandleByPIDq(jinchengid);
            break;
        }
    }

    if(hwndList.size() == 1) {
    	m_HWND_list.append(hwndList.at(0));
        QWindow *pWin = QWindow::fromWinId((WId)hwndList.at(0));//根据句柄获得该窗口
        pWin->setGeometry(0,0,1920,1080);//对窗口设置位置和大小
    }
}
void Widget::closeChrome()
{
    if(chrome_Process) {
        chrome_Process->close();
    }
}
QList<HWND> Widget::GetWindowHandleByPIDq(DWORD dwProcessID)//通过进程ID获取子窗口
{
    QList<HWND> HWND_list;
    HWND h = ::GetTopWindow(0);
    while (h)
    {
        DWORD pid = 0;
        DWORD dwTheardId = GetWindowThreadProcessId(h, &pid);

        if (dwTheardId != 0) {
            if(pid==dwProcessID) {
                TCHAR *name=new TCHAR[MAX_PATH];
                //::GetClassName(h, name, 255);
                ::GetWindowTextW(h, name, 255);
                QString title = QString :: fromStdWString(name);
                if(title.contains("- Google Chrome")&&title!="任务管理器 - Google Chrome") {   //自己打开的窗口都是以- Google Chrom结尾
                    HWND_list.append(h);  //HWND_list记录所有谷歌浏览器下打开的窗口
                    if(m_HWND_list.contains(h)) {   //m_HWND_list存的是之前已经打开并记录下来的窗口  m_HWND_list需自己在头文件定义一下 QList<HWND> m_HWND_list;
                        HWND_list.removeOne(h);//只记录现在打开的窗口
                    }
                }
            }
        }
        h = ::GetNextWindow(h, GW_HWNDNEXT);
    }

    return HWND_list;//返回的最新打开的窗口(就一个)
}
//============================================================================================

http://www.kler.cn/a/2342.html

相关文章:

  • 8位移位寄存器的verilog语言
  • flink实现复杂kafka数据读取
  • 每日十题八股-2024年12月21日
  • Nginx的stream模块代理四层协议TCP的流量转发
  • 练习题 最小栈
  • 中国新能源汽车公共充电桩数据合集(2002-2023年)
  • Qt示例3:用Qt画一个温度计
  • 【thingsboard】实现设备联动
  • 数据结构与算法——二叉树遍历、查找、删除、顺序存储二叉树、线索化二叉树
  • 【数据结构】环形链表
  • 大数据模型、离线架构、实时架构
  • Qt实践项目:仿Everything软件实现一个QtEverything
  • 提高曝光率:外贸网站如何充分利用谷歌优化赢得客户
  • C++成神之路 | 第一课【步入C++的世界】
  • 23种设计模式
  • Linux第一个小程序git三板斧
  • 【28】Verilog进阶 - RAM的实现
  • JAVA开发(自研项目的开发与推广)
  • BeanPostProcessor原理分析
  • Flutter内阴影
  • 人脸识别经典网络-MTCNN(含Python源码实现)
  • 深度学习(22):如何判断训练过程中深度学习模型损失值不再下降
  • Java语言-----类与对象的秘密
  • vue2和vue3中路由的区别和写法?
  • Django(一)安装
  • 计算机网络(第十二弹) --- 传统访问过程与 CDN 访问过程对比