gpt4 book ai didi

c - GTK 按键事件传播要么导致递归,要么不起作用

转载 作者:行者123 更新时间:2023-11-30 16:10:01 24 4
gpt4 key购买 nike

我有一个简单的 GTK 程序,在窗口中包含一个 webkit2 小部件,仅此而已。我希望能够过滤进入 webkit2 小部件的按键。起初,我向 webkit 小部件添加了一个键掩码并添加了一个回调函数,但是在回调函数中传播事件后,它只是递归地调用自身,从而导致崩溃。为了解决这个问题,我将按键掩码附加到主窗口,该窗口是我的 webkit 小部件的父窗口,但这不再阻止输入停止,有时按键释放事件会递归地相互调用。我想知道如何实现我的目标? (我使用了 GTK+ 输入事件处理文档页面上提到的所有不同类型的传播。)

当前按键掩码:

    gtk_widget_add_events(GTK_WIDGET(main_window), GDK_KEY_PRESS_MASK);
g_signal_connect(G_OBJECT(GTK_WIDGET(main_window)), "key_press_event", G_CALLBACK(keypressHandeler), NULL);
g_signal_connect(G_OBJECT(GTK_WIDGET(main_window)), "key_release_event", G_CALLBACK(keypressHandeler), NULL);

当前回调函数(返回只是为了查看当前传播是否有效)

gboolean keypressHandeler(GtkWidget *widget, GdkEventKey *event, gpointer data){
if(event->type == GDK_KEY_PRESS)
printf("Key press\n");
if(event->type == GDK_KEY_RELEASE)
printf("Key release\n");
return gtk_widget_event(GTK_WIDGET(webView), event);
}

最佳答案

代码中的问题是您通过手动模拟信号gtk_widget_event() (https://developer.gnome.org/gtk3/stable/GtkWidget.html#gtk-widget-event)

因此,在第一次调用 keypressHandeler 后,gtk_widget_event 将再次模拟相同的事件,因此它将无限循环运行。

如果您在“keypressHandeler”中返回 false 或 true,您的代码将正常工作

#include <gtk/gtk.h>
#include <webkit2/webkit2.h>



WebKitWebView *webView;

gboolean keypressHandeler(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
if (event->type == GDK_KEY_PRESS)
printf("Key press from mainwindow\n");
if (event->type == GDK_KEY_RELEASE)
printf("Key release\n");

//for the key use want to propogate
if (dont wanna propogate )
{
return TRUE;
} else {
return FALSE;
}

}

gboolean keypressHandeler2(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
if (event->type == GDK_KEY_PRESS)
printf("Key press from webkit\n");
if (event->type == GDK_KEY_RELEASE)
printf("Key release\n");
// set it as TRUE to stop porpogation.. (for some reason it propogating to mainwindow once)
return TRUE;
}

static void destroyWindowCb(GtkWidget* widget, GtkWidget* window);
static gboolean closeWebViewCb(WebKitWebView* webView, GtkWidget* window);

int main(int argc, char* argv[])
{
// Initialize GTK+
gtk_init(&argc, &argv);

// Create an 800x600 window that will contain the browser instance
GtkWidget *main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(main_window), 800, 600);

// Create a browser instance
webView = WEBKIT_WEB_VIEW(webkit_web_view_new());

// Put the browser area into the main window
gtk_container_add(GTK_CONTAINER(main_window), GTK_WIDGET(webView));

// Set up callbacks so that if either the main window or the browser instance is
// closed, the program will exit
gtk_widget_add_events(GTK_WIDGET(main_window), GDK_KEY_PRESS_MASK);
g_signal_connect(G_OBJECT(GTK_WIDGET(main_window)), "key_press_event", G_CALLBACK(keypressHandeler), NULL);
g_signal_connect(G_OBJECT(GTK_WIDGET(webView)), "key_press_event", G_CALLBACK(keypressHandeler2), NULL);
g_signal_connect(G_OBJECT(GTK_WIDGET(main_window)), "key_release_event", G_CALLBACK(keypressHandeler), NULL);
g_signal_connect(G_OBJECT(GTK_WIDGET(webView)), "key_release_event", G_CALLBACK(keypressHandeler2), NULL);

g_signal_connect(main_window, "destroy", G_CALLBACK(destroyWindowCb), NULL);
g_signal_connect(webView, "close", G_CALLBACK(closeWebViewCb), main_window);

// Load a web page into the browser instance
webkit_web_view_load_uri(webView, "http://www.webkitgtk.org/");

// Make sure that when the browser area becomes visible, it will get mouse
// and keyboard events
gtk_widget_grab_focus(GTK_WIDGET(webView));

// Make sure the main window and all its contents are visible
gtk_widget_show_all(main_window);

// Run the main GTK+ event loop
gtk_main();

return 0;
}


static void destroyWindowCb(GtkWidget* widget, GtkWidget* window)
{
gtk_main_quit();
}

static gboolean closeWebViewCb(WebKitWebView* webView, GtkWidget* window)
{
gtk_widget_destroy(window);
return TRUE;
}

如果这就是您的尝试..发生的情况是,当您设置 GDK_KEY_PRESS_MASK 时,它也会反射(reflect)在 webkit 上。

因此,如果您评论“g_signal_connect(G_OBJECT(GTK_WIDGET(main_window)), “key_press_event”, G_CALLBACK(keypressHandeler), NULL);”该程序应该可以正常工作

为主窗口处理程序返回 true 将停止传播到 webview,返回 false 将允许传播。

关于c - GTK 按键事件传播要么导致递归,要么不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58981660/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com