您好,登錄后才能下訂單哦!
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<weikting@gmail.com>. 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 <gtk/gtk.h> #include <glib.h> #include <webkit2/webkit2.h> #include <sys/types.h> #include <unistd.h> static void web_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 gboolean on_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 void on_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 void webkit_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 void on_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); } int main (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<weikting@gmail.com>. 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 <glib.h> #include <webkit2/webkit-web-extension.h> #include <sys/types.h> #include <unistd.h> static gint js_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 void webkit_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
<!DOCTYPE html> <html lang="zh"> <!--filename: webview.html --> <head> <meta charset="utf-8"/> <meta http-equiv="Content-Language" content="zh-CN"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> <meta name="referrer" content="always"/> <title>Webkit Webview test</title> <script type="text/javascript"> function change_span_id(v=''){ //alert("test") document.getElementById('span_id').innerHTML = 'test'+v+gtkValue return v } function native_add(num){ //調用自定義添加的js接口 i= GtkNative.add(num) document.getElementById('add').innerHTML = i } </script> </head> <body> <span>words for test: </span><span id="span_id"></span> <br/> <button onclick="change_span_id()">change span id</button> <br/> <span>Native add: </span><span id='add'></span> <br/> <button onclick="native_add(2)">Native Add</button> </body> </html>
示例運行: 安裝依賴: 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應用內嵌網頁與原生代碼交互方法的示例分析的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。