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;//返回的最新打开的窗口(就一个)
}
//============================================================================================