Several implementation methods of embedding web pages in Qt

1. Background

The interface interaction of Web pages has greater advantages than the Qt client: more diversity and higher ease of use allow us to consider embedding web pages into the client interface even in the client. In this way, the advantages of the web can be combined with the client. To enrich the interface and functions of the client, the following will introduce several common implementation solutions and steps for embedding web pages in Qt clients.

2. Implement scheme design

1. Implemented based on Qt’s own controls

1.1 Introduction

In Qt, a control for accessing web pages is provided (different Qt versions correspond to different control modules), which integrates the browser's webkit kernel and Google's engine. To be loosely speaking, this control is actually a simplified version. browser.
Qt5.0~5.4: webkitwidgets module - QWebView
After Qt5.4: webenginewidgets module - QWebEngineView
Here our client's qt selection is qt5.9.6, so QWebEngineView is used.

1.2 Environment configuration

Qt5.9.6 + VS2015
Note: Check whether the local Qt has the webenginewidgets module. The easiest way is to right-click any Qt project->Qt Project Settings->Qt Modules to check whether the WebEngine Widgets module is gray. If it is gray, it means it is not configured. This module cannot be selected. You need to reinstall Qt and select this module.

1.3 Development process

After configuring the Qt module, it can be used like an ordinary button or label by dragging the ui control or directly using new.
Code example:
Insert image description here

Renderings show:
Insert image description here

1.4 Summary

At this point, a simple Web page has been successfully embedded, but the browser implemented in this way has disadvantages: it cannot decode and play the video, and can only view static pages. Because the browser kernel integrated at the bottom of the Qt component (the kernel of the Chrome browser, the kernel version is determined by the Qt version) does not have a decoding library, video playback cannot be performed. However, you can recompile the source code implementation of this control by adding compilation configuration. Compilation requires higher hardware and takes a long time. Therefore, it is not recommended to use it as a regular solution if there is a need for video playback function.

2. Implementation by embedding Chrome.exe process

2.1 Introduction

There is no functional difference between this implementation method and the local Chrome browser. The functions that can be implemented in the local browser are still normal when embedded in the Qt window in this way. The essence of the implementation is to start the browser process from the client and pass the corresponding url and other parameters, then obtain the window handle through the Windows API, and then convert the window handle to QWigetde to achieve embedding.

2.2 Environment configuration

Qt5.9.6 + VS2015

Depends on local Chrome, so Google Chrome must be downloaded and installed first.

2.3 Development process
2.3.1 Detect whether the browser exists

Check whether Google Chrome has been installed. If not, prompt to install it. If it is already installed, use Qt's QProcess to start Chrome.exe and pass the parameters required by the browser process.
To start Chrome.exe, you need to first obtain the path of the exe. Although the path of Google Chrome is installed by default, the path is also very different on different machines. Therefore, it cannot be obtained by traversing a certain folder or a fixed path. Here, you can use the method of reading the registry to obtain the path of chrome.exe. The registry read here is the current user (HKEY_CURRENT_USER). However, in actual situations, the registry of chrome is not necessarily under the current user. If it is not under the current user, you can continue to query the registry of the local machine (HKEY_LOCAL_MACHINE). You can do it yourself. Add a judgment branch. The sample code is as follows:
Insert image description here

2.3.2 Reading and embedding of window handles

After starting the browser, you must first obtain the class name and title of the window through the spy++ tool. To use spy++, open VS->Click Tools on the menu bar->Click spy+±>Click Search->Find Window->Drag the bullseye to the window you want to obtain.
Then use the Windows API: FindWindow(L"Chrome_WidgetWin_1", NULL); to obtain the window handle of the browser. The parameter entered here cannot be the title name. It should be obtained through the class name, because the title name can change from different addresses. The title Once the name is changed, the window handle cannot be obtained.
After successfully obtaining the handle, convert the handle to QWindow *pWin = QWindow::fromWinId(wid);
Finally, create a window container: QWidget *pWid = QWidget::createWindowContainer(pWin, this); The returned pWid can be filled in through the layout Go to the corresponding interface of Qt.
The complete code is as follows:
Insert image description here

After startDetached starts the browser, the main thread must sleep for three seconds. This operation cannot be omitted. If the sleep operation is not performed, embedding may fail.
The process parameters of chrome.exe here: -chrome-frame is a required parameter for startup; -kiosk parameter is for startup without displaying the title bar. For other startup parameters, please refer to the following document:
https://www.cnblogs.com/yikemogutou/p/12624113.html

2.4 Summary

Although this method can achieve complete functions, it also has certain uncontrollable flaws: here is the chrome browser started with parameters, which is configured to be full screen and without a title bar when started. Then after opening the client and then opening the browser, the opened browser will still be full screen and without a title bar. If the user starts the browser first and then starts the client. Then the client's process parameters will not take effect, and the embedded web page will display the title bar and address. This is obviously unreasonable.

3. CEF3 implementation based on Chrome

3.1 Introduction

CEF, the full name of Chromium Embedded Framework, is an open source project based on Google Chromium. The Google Chromium project is primarily developed for Google Chrome applications, while the goal of CEF is to provide embeddable browser support for third-party applications. The function of CEF is to embed the web interface on the client side.
CEF itself does not support video playback. If you need to support it, you need to recompile the chromium source code. You can refer to CEF's official documentation for the compilation operation:
https://wiki.hikvision.com.cn/pages/viewpage.action? pageId=168565259
Since compilation requires downloading CEF and chromium source code, a stable external network environment is required. We don't have that here. So here I found a compiled version on the Internet that is more in line with expectations and can be used directly.

3.2 Environment configuration

Qt5.9.6 + VS2015

3.3 Development process
3.3.1. cef project configuration compilation

After downloading the cef package, you can see that there is an official website demo inside. Here we can refer to this sample document to build our own project.
Insert image description here

The first step is to create an empty project, add the following five source files and resource files under the project, and add main.cpp. Here, open the exception with the suffix cpp and change it to _cpp. You can adjust it yourself later.
Insert image description here
The second step is to add the path to the include directory and the include path to the static library. The following three static library files are used here. The static library files are included in the CEF package. Since the library files are compiled for debug, the project should also be configured in debug mode accordingly.
Insert image description here

Step 3: Since the runtime library after creating the project defaults to MDD, but because the runtime library of the static library file is MTD, it is necessary to change the runtime library of the project to MTD synchronously.
Insert image description here

The fourth step requires adding the CefFrame.manifest file in the same directory as main.cpp and adding the file path in the manifest input of the project properties.
Insert image description here

At this point, the cef project file can be compiled. The next step is to make corresponding corrections according to your own needs.

3.3.2. Implementation process description

What I still use here is to start the cef process, pass the process parameters (that is, the URL to be accessed) at startup, and then pass parameters between processes to access the web page for this purpose. Finally, the cef process is embedded into the client. The embedding scheme here is slightly different from before. If you still use the spy++ tool and Windows API to obtain the window handle, it is not feasible and the result will always be empty. Therefore, inter-process communication (shared memory) is used here to transfer the window handle (cef's window handle can be obtained by itself).
Here is an appropriate delay after the client starts cef to ensure that the cef process has written the window handle data to the shared memory (of course this can be replaced with a better while loop until the handle value is read and the loop body exits) , can be considered as an optimization item), and finally convert the handle to QWindow *pWin = QWindow::fromWinId(wid);
Finally, create a window container: QWidget *pWid = QWidget::createWindowContainer(pWin, this); This returned pWid It can be filled into the corresponding interface of Qt through layout. Some code examples are as follows:
the handle is written to shared memory:
Insert image description here

Read handle from shared memory:
Insert image description here

3.4 Summary

Due to the limitations of the company's intranet, this solution cannot directly download the source code of chromium and cef for compilation. It can only find compiled library files that support the mp4 format online. The version of chromium corresponding to the cef library file here is relatively small. Low, there are limitations in the decoding part and cannot meet actual user requirements.

4. Implementation based on Microsoft's WebView2

4.1 Introduction

The Microsoft Edge WebView2 control allows you to embed web technologies (HTML, CSS, and JavaScript) in native applications. The WebView2 control uses Microsoft Edge as the rendering engine to display web content in native applications. Using WebView2, you can embed Web code into different parts of a native application, or build all native applications in a single WebView instance.
Insert image description here

4.2 Environment configuration

Qt5.9.6 + VS2015
operating environment must install the running package of WebView2: MicrosoftEdgeWebView2RuntimeInstallerX64.exe
can be downloaded from Microsoft official: https://developer.microsoft.com/zh-cn/microsoft-edge/webview2/

4.3 Development process

Our purpose is to embed web pages in Qt, but currently there is no way to directly embed webview2 into the Qt client, so we still use the method of reading the window handle of the process to embed the entire process. So here we will use the win32 sample program of webview2 as an example to explain the development.

4.3.1. WebView2 project configuration

First, go to the official website to download the corresponding win32 sample document [Win32_GettingStarted] for webview2, open it with vs2015, right-click the WebView2GettingStarted project -> select Configuration Properties > General to check whether the corresponding target platform version [
WindowsSDK] and platform tool set are correct.
Insert image description here

The platform version here must be 10.0 or above, otherwise the following error will be reported when compiling. If it is not 10.0 or above, you can download the new SDK from the Windows official website.
Insert image description here

4.3.2. Install Windows Implementation Library (WIL)

After configuring the SDK, you need to configure the corresponding Windows Implementation Library (WIL). Here, in the Solution Explorer, right-click the WebView2GettingStarted project node, and then select Manage NuGet Package. In the NuGet window, click the "Browse" tab. In the search bar in the upper left corner, enter Microsoft.Windows.ImplementationLibrary, and then select to install this package.
Insert image description here

4.3.3. Install WebView2 SDK

This step requires configuring the SDK of webview2. Here in the Solution Explorer, right-click the WebView2GettingStarted project node, and then select Manage NuGet Package. In the NuGet window, click the "Browse" tab in the search bar in the upper left corner , enter Microsoft.Web.WebView2, and then select to install this package.
Insert image description here

4.3.4. Implementation process description

What is used here is to start the exe in the client process. After the startup is successful, the window handle is found through spy++ to implement the logic embedded in the client. Therefore, the final accessed URL is still passed from the client to the exe of webview2 through the main function. , the webview process accesses the destination web page after obtaining the url. There is a small detail that needs to be noted here. Since the original code is implemented as a double lambda expression, the variable cannot be passed directly. This variable needs to be added to the capture list, as follows:
Insert image description here

At this point, the entire process can be implemented, but currently there is a title bar and buttons in the webview interface, which we do not need, so in the last step, we need to hide the title bar and buttons, and only need a borderless interface. That’s it. The relevant code is as follows:
Insert image description here

4.4 Summary

At this point, a simple program based on the WebView2 control has been successfully implemented. It can be found that although WebView is simpler and has better functions and user experience than other implementation methods, this implementation method also has a fundamental shortcoming: this The implementation of Windows-based SDK cannot be localized. Therefore, this solution can still be adopted as the optimal solution without considering localization.

3. Summary

Through the introduction of the above four solutions for embedding web pages in Qt clients, we can roughly understand that the first solution can be the first choice when only the web page needs to be displayed and has nothing to do with video playback; when video playback is required If there are sufficient external network and hardware resources available, the third option is to reprogram the CEF and chromium source code according to your own needs; if you need to play video and do not have the above resources. Optional WebView solution can be implemented. As for the implementation plan of embedding chrome.exe, comprehensively speaking, it cannot meet the actual usage scenarios of users and there are many uncontrollable factors. Therefore, it is summarized here as a negative case.

Guess you like

Origin blog.csdn.net/qq_37735986/article/details/124629321