GTK按键事件传播导致递归或不起作用 [英] GTK keypress event propagation either causes recursion or does not work

查看:80
本文介绍了GTK按键事件传播导致递归或不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a simple GTK program containing a single webkit2 widget in a window and nothing else. I want to be able to filter the keypresses going to the webkit2 widget. At first I added a key mask to the webkit widget and added a callback function, however after propogating the event in the callback function it just calls itself recursively which results in a crash. To resolve this I attached my key mask to the main-window, which is parent to my webkit widget, however this no longer prevents input from getting stopped and sometimes key release events recursively call each other. I was wondering how to achieve my goal? (I've used all different types of propogation mentioned on the GTK+ input event handeling documentation page.)

当前键盘掩码:

    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);

当前的回调函数(返回值只是查看传播是否在当前起作用)

current callback function (the return is just to see if the propogation worked at the moment)

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 )

The problem in your code is that you're manually simulating the signal through gtk_widget_event() (https://developer.gnome.org/gtk3/stable/GtkWidget.html#gtk-widget-event)

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

so after the first time keypressHandeler gets called gtk_widget_event will simulate the same event again so it will run in an endless loop.

如果您在"keypressHandeler"中返回false或true,则您的代码将可用

if you return false or true in "keypressHandeler" your code will work

#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时,它也反映在Webkit上.

If this what your trying.. whats happening is that when you set GDK_KEY_PRESS_MASK it is also being reflected on the webkit.

因此,如果您评论"g_signal_connect(G_OBJECT(GTK_WIDGET(main_window)),"key_press_event",G_CALLBACK(keypressHandeler),NULL);" 该程序应该可以正常运行

so if you comment " g_signal_connect(G_OBJECT(GTK_WIDGET(main_window)), "key_press_event", G_CALLBACK(keypressHandeler), NULL);" the program should work fine

为mainwindow处理程序返回true将停止传播到webview,而返回false将允许传播.

returning true for mainwindow handler will stop the propagation to the webview and returning false will allow propagation.

这篇关于GTK按键事件传播导致递归或不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆