如何在GTK中获得键盘和鼠标输入

How do I get Keyboard and Mouse Input in GTK?

本文关键字:键盘 鼠标 输入 GTK      更新时间:2023-10-16

我想在GTK+中接收键盘和鼠标输入。对于键盘输入,我尝试使用加速组,但它不像SDL或SFML那样顺畅。当我按下一个键。它响应,暂停一段时间,再次响应,暂停一段时间,以此类推。我所说的鼠标输入是指在给定时间获取鼠标的位置以及是否点击了鼠标按钮。通过键盘输入,我想跟踪按键和释放。我正在使用GTK+和cairo的教育图形程序。有点像海龟图形。任何帮助吗?或者使用GTK+并跟踪键盘和鼠标输入的任何第三方库(C或c++) ?

您要做的事情比较复杂。看一看

http://developer.gnome.org/gtk-tutorial/2.90/

,尤其是

http://developer.gnome.org/gtk-tutorial/2.90/x344.html

http://developer.gnome.org/gtk-tutorial/2.90/c2422.html

第二个链接有键盘回调的源代码,它似乎可以做你想做的事情。第三个链接是一个使用鼠标的简单绘图程序教程的开始。

编辑:为了完整起见,我将提到gtkgleext库支持在GTK+中使用OpenGL。看到http://projects.gnome.org/gtkglext/

根据文档]1你可以得到鼠标运动事件设置它们的掩码GDK_POINTER_MOTION_MASK -这意味着你会得到运动事件,即使没有按钮被按下。此外,Gtk+教程还展示了一些利用鼠标移动事件的概念。

当我按下一个键。它响应,暂停一段时间,再次响应,暂停一段时间,等等。

你这话是什么意思?我认为你是在描述键重复行为(就像在文本编辑器中,当你按下'a'并按住它时,你会得到'aaaaaaaaaaa ')。在你的应用程序中禁用它:

XKeyboardControl control; 
control.auto_repeat_mode = 0; 
gdk_error_trap_push (); 
XChangeKeyboardControl (GDK_DISPLAY (), KBAutoRepeatMode, &control); 
gdk_error_trap_pop (); 

下面是一个示例代码演示如何使用回调来注册鼠标移动和按键:

// compile with: gcc example.c `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0`
#include <stdio.h>
#include <gtk/gtk.h>
static gboolean is_w_pressed = FALSE;
static gboolean is_a_pressed = FALSE;
static gboolean is_s_pressed = FALSE;
static gboolean is_d_pressed = FALSE;
static gboolean is_q_pressed = FALSE;
static gboolean is_e_pressed = FALSE;
static gboolean mouse_moved(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
    if (event->type == GDK_MOTION_NOTIFY)
    {
        GdkEventMotion *e = (GdkEventMotion*)event;
        printf("Coordinates: (%u, %u)n", (guint)e->x, (guint)e->y);
    }
}
static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
    if (event->keyval == GDK_KEY_w)
    {
        is_w_pressed = TRUE;
        return TRUE;
    }
    else if (event->keyval == GDK_KEY_a)
    {
        is_a_pressed = TRUE;
        return TRUE;
    }
    else if (event->keyval == GDK_KEY_s)
    {
        is_s_pressed = TRUE;
        return TRUE;
    }
    else if (event->keyval == GDK_KEY_d)
    {
        is_d_pressed = TRUE;
        return TRUE;
    }
    return FALSE;
}
static gboolean key_released(GtkWidget *widget, GdkEventKey *event)
{
    if (event->keyval == GDK_KEY_w) {
        is_w_pressed = FALSE;
    }
    if (event->keyval == GDK_KEY_a) {
        is_a_pressed = FALSE;
    }
    if (event->keyval == GDK_KEY_s) {
        is_s_pressed = FALSE;
    }
    if (event->keyval == GDK_KEY_d) {
        is_d_pressed = FALSE;
    }
    return GDK_EVENT_PROPAGATE;
}
gboolean update (GtkWidget *widget, GdkFrameClock *clock, gpointer data)
{
    if (is_w_pressed) {
        printf("W key pressed!n");
    }
    if (is_a_pressed) {
        printf("A key pressed!n");
    }
    if (is_s_pressed) {
        printf("S key pressed!n");
    }
    if (is_d_pressed) {
        printf("D key pressed!n");
    }
    printf("updating...n");
}
int main(int argc, char *argv[]) {
    GtkWidget *window;
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_events(window, GDK_KEY_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_POINTER_MOTION_MASK);
    gtk_widget_set_size_request(window, 320, 240);
    g_signal_connect(G_OBJECT(window), "motion-notify-event", G_CALLBACK(mouse_moved), NULL);
    g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(key_pressed), NULL);
    g_signal_connect(G_OBJECT(window), "key_release_event", G_CALLBACK(key_released), NULL);
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_widget_add_tick_callback(window, update, NULL, NULL);
    gtk_widget_show_all(window);
    gtk_main(); 
    return 0;
}