千家信息网

Gtk应用内嵌网页与原生代码交互方法的示例分析

发表于:2025-01-22 作者:千家信息网编辑
千家信息网最后更新 2025年01月22日,Gtk应用内嵌网页与原生代码交互方法的示例分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Gtk应用内嵌网页与原生代码交互方法关键词:
千家信息网最后更新 2025年01月22日Gtk应用内嵌网页与原生代码交互方法的示例分析

Gtk应用内嵌网页与原生代码交互方法的示例分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

Gtk应用内嵌网页与原生代码交互方法

关键词: gtk webikit webview javascript 内嵌网页 js对象 WebKitWebExtension

在使用Gtk开发应用程序的过程中,如果需要内嵌网页,那么使用libwebkit2gtk是个非常自然和正确的选择。那么这里就可能原生程序代码可能需要跟网页交互的问题。

Gtk程序跟网页的交互,主要有两个方面: 1 Gtk程序需要调用网页js代码 2 网页需要调用Gtk程序的功能代码

需求1,使用webkit2gtk的内置webkit_web_view_run_javascript函数即可解决 需求2,使用webkit2gtk的内置的web extendsion扩展支持功能解决

不多说看代码吧!

Gtk嵌入网页程序示例,webviewgtk.c

/**** Copyright (C) 2020 Wei Keting. All rights reserved.* @Time : 2021-04-04 12:18* @File : webviewgtk.c* @Description :** 依赖下载:* sudo apt install libwebkit2gtk-4.0-doc libwebkit2gtk-4.0-dev libgtk-3-dev* gcc webviewgtk.c -o webviewgtk -D_GNU_SOURCE -g3 -Wall `pkg-config --cflags --libs webkit2gtk-4.0`**/#include #include #include #include #include static voidweb_view_javascript_finished (GObject      *object,                              GAsyncResult *result,                              gpointer      user_data){    WebKitJavascriptResult *js_result;    JSCValue               *value;    GError                 *error = NULL;    js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (object), result, &error);    if (!js_result) {        g_warning ("Error running _javascript: %s", error->message);        g_error_free (error);        return;    }    value = webkit_javascript_result_get_js_value (js_result);    if (jsc_value_is_string (value)) {        JSCException *exception;        gchar        *str_value;        str_value = jsc_value_to_string (value);        exception = jsc_context_get_exception (jsc_value_get_context (value));        if (exception)            g_warning ("Error running _javascript: %s", jsc_exception_get_message (exception));        else            g_print ("Script result: %s\n", str_value);        g_free (str_value);    } else {        g_warning ("Error running _javascript: unexpected return value");    }    webkit_javascript_result_unref (js_result);}static gbooleanon_webview_load_failed(WebKitWebView  *webview,               WebKitLoadEvent load_event,               gchar          *failing_uri,               GError         *error,               gpointer        user_data){    g_printerr("%s: %s\n",failing_uri,error->message);    return FALSE;}static voidon_button_clicked(GtkButton *button,               WebKitWebView *webview){    static gint t = 0;    gchar buf[128]={0};    g_snprintf(buf,sizeof(buf)-1,"change_span_id('_n%d')",t);    t+=1;    //在webview当前的html页面中直接运行js代码    webkit_web_view_run_javascript(webview,buf,NULL,web_view_javascript_finished,NULL);}static voidwebkit_web_extension_initialize (WebKitWebContext *context,               gpointer          user_data){    g_printerr("%s: %d\n",__FUNCTION__,getpid());    //设置web extendsion扩张.so文件的搜索目录    webkit_web_context_set_web_extensions_directory(context,".");}/**** 创建window,添加webkit控件****/static voidon_activate (GtkApplication *app){        GtkWindow *window;        g_assert (GTK_IS_APPLICATION (app));        window = gtk_application_get_active_window (app);        if (window == NULL)                window = g_object_new (GTK_TYPE_WINDOW,                                       "application", app,                                       "default-width", 600,                                       "default-height", 300,                                       NULL);    //注册处理web extensions的初始化函数    g_signal_connect(webkit_web_context_get_default(),"initialize-web-extensions",G_CALLBACK(webkit_web_extension_initialize),NULL);    GtkWidget* webview = webkit_web_view_new();    g_signal_connect (webview, "load-failed", G_CALLBACK (on_webview_load_failed), NULL);    // 加载网页    GFile *file = g_file_new_for_path("webview.html");    gchar *uri = g_file_get_uri(file);    webkit_web_view_load_uri(WEBKIT_WEB_VIEW(webview), uri);    g_free(uri);    g_object_unref(file);        GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);    GtkWidget *button = gtk_button_new_with_label ("change span");    gtk_box_pack_start(GTK_BOX(vbox),GTK_WIDGET(webview),TRUE,TRUE,0);    gtk_box_pack_start(GTK_BOX(vbox),GTK_WIDGET(button),FALSE,TRUE,0);        gtk_container_add(GTK_CONTAINER(window),GTK_WIDGET(vbox));    gtk_widget_show_all(GTK_WIDGET(vbox));    gtk_window_present (window);        g_signal_connect (button, "clicked", G_CALLBACK (on_button_clicked), webview);}intmain (int   argc,      char *argv[]){        g_autoptr(GtkApplication) app = NULL;        int ret;        app = gtk_application_new ("com.weiketing.webkit_webview", G_APPLICATION_FLAGS_NONE);        g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL);        ret = g_application_run (G_APPLICATION (app), argc, argv);        return ret;}

web extension实现代码示例,web_exten.c

/**** Copyright (C) 2020 Wei Keting. All rights reserved.* @Time : 2021-04-04 12:18* @File : web_exten.c* @Description :** 依赖下载:* sudo apt install libwebkit2gtk-4.0-doc libwebkit2gtk-4.0-dev libgtk-3-dev* gcc  web_exten.c -o libweb_exten.so -shared -Wl,-soname,libweb_exten.so -D_GNU_SOURCE -g3 -Wall `pkg-config --cflags --libs webkit2gtk-4.0`**/#include #include #include #include static gintjs_app_add(gpointer *first,gint num){    static gint N = 0;    g_printerr("%s: %p\n",__FUNCTION__,first);    N += num;    return N;}static void window_object_cleared_callback (WebKitScriptWorld *world,                                 WebKitWebPage     *web_page,                                 WebKitFrame       *frame,                                 gpointer           user_data){    JSCContext* jsContext;    jsContext = webkit_frame_get_js_context_for_script_world (frame, world);    //添加一个js全局变量gtkValue    jsc_context_set_value(jsContext,"gtkValue",jsc_value_new_string(jsContext,"__test_js_exten"));    /* Use JSC API to add the JavaScript code you want */        //注册一个名为NativeTest的js类    JSCClass* app = jsc_context_register_class(jsContext,"NativeTest",NULL,NULL,NULL); // g_object_new(JSC_TYPE_CLASS,"name","JSApp","context",jsContext,NULL);    //给JSCClass类添加add方法    jsc_class_add_method(app,"add",G_CALLBACK(js_app_add),NULL,NULL,G_TYPE_INT,1,G_TYPE_INT,NULL);    //创建一个obj,作为JSCClass类绑定实例,JSCClass方法回调的第一个参数就是obj    GObject *obj = g_object_new(G_TYPE_OBJECT,NULL);    jsc_context_set_value(jsContext,"GtkNative",jsc_value_new_object(jsContext,obj,app));    g_printerr("%s: %d %p\n",__FUNCTION__,getpid(),obj);    g_object_unref(obj);}G_MODULE_EXPORT voidwebkit_web_extension_initialize (WebKitWebExtension *extension){    //web extension的初始化函数    g_signal_connect (webkit_script_world_get_default (),                       "window-object-cleared",                       G_CALLBACK (window_object_cleared_callback),                       NULL);}

内嵌的网页示例,webview.html

                    Webkit Webview test        words for test:     

Native add:

示例运行: 安装依赖: sudo apt install libwebkit2gtk-4.0-doc libwebkit2gtk-4.0-dev libgtk-3-dev

把webviewgtk.c,web_exten.c, webview.html放在同一目录下。 编译程序:

gcc  web_exten.c -o libweb_exten.so -shared -Wl,-soname,libweb_exten.so -D_GNU_SOURCE -g3 -Wall `pkg-config --cflags --libs webkit2gtk-4.0`gcc webviewgtk.c -o webviewgtk -D_GNU_SOURCE -g3 -Wall `pkg-config --cflags --libs webkit2gtk-4.0`

运行程序:

./webviewgtk

看完上述内容,你们掌握Gtk应用内嵌网页与原生代码交互方法的示例分析的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

0