本文作者:icy

C++ WebView:轻量级跨平台Web视图库

icy 昨天 12 抢沙发
C++ WebView:轻量级跨平台Web视图库摘要: C++ WebView:轻量级跨平台Web视图库 项目概述 C++ WebView 是一个轻量级、跨平台的库,允许开发者在C++应用程序中嵌入Web视图(基于Chromium/We...

C++ WebView:轻量级跨平台Web视图库

C++ WebView:轻量级跨平台Web视图库

项目概述

C++ WebView 是一个轻量级、跨平台的库,允许开发者在C++应用程序中嵌入Web视图(基于Chromium/WebKit)。该项目提供了一个简单的API,让开发者能够轻松地将现代Web技术(HTML、CSS、JavaScript)集成到原生桌面应用中。

核心特性

1. 跨平台支持

  • Windows: 使用Microsoft Edge WebView2
  • macOS: 使用WKWebView
  • Linux: 使用WebKitGTK
  • 无需额外依赖,自动适配各平台原生Web引擎

2. 轻量级API

  • 简洁的C接口,易于集成
  • 头文件仅需单个webview.h
  • 最小化依赖,编译简单

3. 双向通信

  • JavaScript调用C++函数
  • C++调用JavaScript函数
  • 支持异步通信

基本用法示例

示例1:创建简单WebView窗口

text
#include "webview.h"

int main() {
    // 创建WebView窗口
    webview::webview w(true, nullptr);
    
    // 设置窗口标题和大小
    w.set_title("C++ WebView示例");
    w.set_size(800, 600, WEBVIEW_HINT_NONE);
    
    // 加载HTML内容
    w.set_html(R"(
        <!DOCTYPE html>
        <html>
        <head>
            <style>
                body {
                    font-family: Arial, sans-serif;
                    padding: 20px;
                    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                    color: white;
                }
                h1 { text-align: center; }
                button {
                    padding: 10px 20px;
                    background: white;
                    color: #667eea;
                    border: none;
                    border-radius: 5px;
                    cursor: pointer;
                    font-size: 16px;
                }
            </style>
        </head>
        <body>
            <h1>欢迎使用C++ WebView!</h1>
            <p>这是一个嵌入在C++应用中的Web页面。</p>
            <button onclick="window.external.invoke('buttonClicked')">
                点击我
            </button>
        </body>
        </html>
    )");
    
    // 绑定JavaScript回调
    w.bind("buttonClicked", [](const std::string& seq, const std::string& req, void* arg) {
        std::cout << "按钮被点击了!" << std::endl;
    });
    
    // 运行主循环
    w.run();
    
    return 0;
}

示例2:双向通信

text
#include "webview.h"
#include <iostream>
#include <thread>

class WebApp {
private:
    webview::webview w;
    int counter = 0;

public:
    WebApp() : w(true, nullptr) {
        w.set_title("双向通信示例");
        w.set_size(800, 600, WEBVIEW_HINT_NONE);
        
        // 绑定C++函数供JavaScript调用
        w.bind("getDataFromCpp", [this](const std::string& seq, 
                                        const std::string& req, 
                                        void* arg) {
            // 返回数据给JavaScript
            std::string response = R"({"message": "来自C++的数据", "count": )" + 
                                  std::to_string(counter++) + "}";
            w.resolve(seq, 0, response);
        });
        
        w.bind("showNotification", [](const std::string& seq, 
                                      const std::string& req, 
                                      void* arg) {
            std::cout << "JavaScript通知: " << req << std::endl;
        });
        
        // 加载HTML界面
        w.set_html(R"(
            <!DOCTYPE html>
            <html>
            <head>
                <style>
                    body { font-family: Arial; padding: 20px; }
                    .container { max-width: 600px; margin: 0 auto; }
                    button { margin: 10px; padding: 10px 20px; }
                    #result { margin-top: 20px; padding: 10px; background: #f0f0f0; }
                </style>
            </head>
            <body>
                <div class="container">
                    <h1>双向通信演示</h1>
                    <button onclick="callCppFunction()">调用C++函数</button>
                    <button onclick="callJsFromCpp()">等待C++调用</button>
                    <div id="result"></div>
                </div>
                <script>
                    function callCppFunction() {
                        window.external.invoke('getDataFromCpp', '', function(data) {
                            document.getElementById('result').innerHTML = 
                                '收到C++响应: ' + JSON.stringify(data);
                        });
                    }
                    
                    function callJsFromCpp() {
                        document.getElementById('result').innerHTML = 
                            '等待C++调用...';
                    }
                    
                    // 这个函数将被C++调用
                    function updateFromCpp(message) {
                        document.getElementById('result').innerHTML = 
                            'C++调用了JS: ' + message;
                        // 发送通知回C++
                        window.external.invoke('showNotification', 
                            'JS收到消息: ' + message);
                    }
                </script>
            </body>
            </html>
        )");
    }
    
    void run() {
        // 启动一个线程定期从C++调用JavaScript
        std::thread([this]() {
            int i = 0;
            while (true) {
                std::this_thread::sleep_for(std::chrono::seconds(3));
                
                // 在UI线程中执行JavaScript
                w.dispatch([this, i]() {
                    std::string js = "updateFromCpp('这是第" + 
                                   std::to_string(i) + "次调用')";
                    w.eval(js);
                });
                
                i++;
            }
        }).detach();
        
        w.run();
    }
};

int main() {
    WebApp app;
    app.run();
    return 0;
}

示例3:加载外部URL

text
#include "webview.h"

int main() {
    webview::webview w(true, nullptr);
    
    w.set_title("加载外部网页");
    w.set_size(1024, 768, WEBVIEW_HINT_NONE);
    
    // 加载外部URL
    w.navigate("https://github.com/webview/webview");
    
    // 添加自定义JavaScript
    w.init(R"(
        // 页面加载完成后执行
        window.addEventListener('DOMContentLoaded', function() {
            // 修改页面样式
            document.body.style.backgroundColor = '#f5f5f5';
            
            // 添加自定义元素
            var banner = document.createElement('div');
            banner.innerHTML = '<h3>通过C++ WebView加载</h3>';
            banner.style.cssText = 'background: #4CAF50; color: white; padding: 10px; text-align: center;';
            document.body.insertBefore(banner, document.body.firstChild);
        });
    )");
    
    w.run();
    return 0;
}

编译和集成

CMake集成

text
cmake_minimum_required(VERSION 3.14)
project(MyWebViewApp)

# 添加webview作为子模块或下载
add_subdirectory(webview)

add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE webview)

直接编译

text
# Linux
g++ -std=c++11 main.cpp -o app `pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.0`

# macOS
g++ -std=c++11 main.cpp -o app -framework WebKit

# Windows (使用vcpkg安装webview2)
cl /EHsc main.cpp webview.cc user32.lib ole32.lib oleaut32.lib

实际应用场景

1. 混合桌面应用

将Web技术用于UI,C++处理业务逻辑和性能敏感任务。

2. 应用内浏览器

在应用中嵌入浏览器功能,如显示帮助文档、用户协议等。

3. 现代UI开发

使用React、Vue等现代前端框架构建应用界面。

4. 原型开发

快速构建具有现代界面的应用原型。

优势与局限

优势:

  • 简单易用:API设计简洁,学习成本低
  • 无运行时依赖:使用系统原生Web引擎
  • 性能优秀:直接调用系统组件,无额外开销
  • 内存占用小:相比完整Electron应用更轻量

局限:

  • 功能相对基础:相比Electron功能较少
  • 平台差异:不同平台的Web引擎特性可能略有不同
  • 调试支持:需要依赖各平台自带的开发者工具

总结

C++ WebView为C++开发者提供了一个优雅的解决方案,将现代Web技术集成到传统桌面应用中。它特别适合需要Web UI的灵活性,同时又需要C++性能优势的应用场景。通过简单的API和跨平台支持,开发者可以快速构建具有现代界面的桌面应用,而无需学习复杂的GUI框架。

项目持续维护中,社区活跃,是构建轻量级混合应用的优秀选择。

webview_20260204211844.zip
类型:压缩文件|已下载:0|下载方式:免费下载
立即下载
文章版权及转载声明

作者:icy本文地址:https://www.zelig.cn/2026/02/236.html发布于 昨天
文章转载或复制请以超链接形式并注明出处软角落-SoftNook

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

阅读
分享

发表评论

快捷回复:

验证码

评论列表 (暂无评论,12人围观)参与讨论

还没有评论,来说两句吧...