Как получить ввод с клавиатуры и мыши в GTK? - PullRequest
2 голосов
/ 08 октября 2011

Я хочу получить ввод с клавиатуры и мыши в GTK +. Для ввода с клавиатуры я попытался использовать Accelgroup, но это было не так гладко, как, скажем, SDL или SFML. Когда я нажал клавишу. Он ответил, остановился на некоторое время, ответил снова, на некоторое время остановился и так далее. Под вводом мыши я имею в виду получение положения мыши в данный момент времени и нажатие кнопки мыши. По вводу с клавиатуры я хочу отслеживать нажатия и отпускание клавиш Я использую GTK + и Каир для образовательной графической программы. Вроде как Черепаха Графика. Любая помощь? Или любая сторонняя библиотека (C или C ++), которая работает с GTK + и отслеживает ввод с клавиатуры и мыши?

Ответы [ 3 ]

2 голосов
/ 08 октября 2011

То, что вы хотите сделать, в меру сложное.Взгляните на

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

Вторая ссылка содержит исходный код для обратного вызова с клавиатуры, который, кажется, делает то, что вы хотите.Третья ссылка - начало учебника для простой программы для рисования, в которой используется мышь.

РЕДАКТИРОВАТЬ: Ради полноты я упомяну, что библиотека gtkglext поддерживает использование OpenGL в GTK +.См

http://projects.gnome.org/gtkglext/

0 голосов
/ 02 марта 2019

Вот пример кода, демонстрирующий, как использовать обратные вызовы для регистрации движения мыши и нажатия клавиш:

// 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;
}
0 голосов
/ 08 октября 2011

Согласно документам] 1 вы можете получить события движения мыши, установив им маску GDK_POINTER_MOTION_MASK - это означает, что вы получите события движения, даже если ни одна кнопка не нажата. Кроме того, Gtk + tutorials показывают некоторые понятия об использовании событий движения мыши.

Когда я нажал клавишу. Он ответил, приостановился на некоторое время, снова ответил, на некоторое время остановился и так далее.

Что вы подразумеваете под этим? Я думаю, что вы описываете повторное поведение клавиш (так же, как в текстовом редакторе, когда вы нажимаете «a» и удерживаете его, вы получаете «aaaaaaaaaaaaa». Чтобы отключить его в вашем приложении :

XKeyboardControl control; 
control.auto_repeat_mode = 0; 

gdk_error_trap_push (); 
XChangeKeyboardControl (GDK_DISPLAY (), KBAutoRepeatMode, &control); 
gdk_error_trap_pop (); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...