C:使用 GTk+ 跟踪鼠标移动

标签 c gtk

考虑以下代码:

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


static void destroy(GtkWidget*, gpointer);
static gboolean mouse_moved(GtkWidget *widget,GdkEvent *event,gpointer user_data);

int main(int argc, char* argv[]) {

    GtkWidget *main_window;

    // initializing
    gtk_init(&argc, &argv);

    main_window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(main_window),"Test");
    gtk_widget_set_size_request (main_window, 500, 300);

    // connect the window with signals
    g_signal_connect (G_OBJECT (main_window), "destroy",G_CALLBACK (destroy), NULL);
    g_signal_connect (G_OBJECT (main_window), "motion-notify-event",G_CALLBACK (mouse_moved), NULL);

    gtk_widget_set_events(main_window, GDK_POINTER_MOTION_MASK);

    // show window
    gtk_widget_show_all (main_window);

    gtk_main();
    return 0;
}


static void destroy(GtkWidget *window,gpointer data) {
    gtk_main_quit ();
}


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

当我从终端运行这段代码时,它会打开一个空窗口,并每次都打印出鼠标坐标。
这是上次执行的(部分)输出:

Coordinates: (390,17)
Coordinates: (390,18)
Coordinates: (390,18)
Coordinates: (390,18)
Coordinates: (390,18)
Coordinates: (390,19)
Coordinates: (390,19)
Coordinates: (390,19)
Coordinates: (391,22)
Coordinates: (391,22)
Coordinates: (391,22)
Coordinates: (391,22)
Coordinates: (391,22)
Coordinates: (391,22)
Coordinates: (391,22)
Coordinates: (391,23)
Coordinates: (391,23)
Coordinates: (391,23)
Coordinates: (390,23)
Coordinates: (390,23)
Coordinates: (390,23)
Coordinates: (390,23)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,25)
Coordinates: (390,25)
Coordinates: (390,25)
Coordinates: (390,25)
Coordinates: (390,25)
Coordinates: (390,25)
Coordinates: (390,26)
Coordinates: (390,26)
Coordinates: (390,26)
Coordinates: (390,26)
Coordinates: (390,26)
Coordinates: (390,26)
Coordinates: (390,26)
Coordinates: (390,27)
Coordinates: (390,27)
Coordinates: (390,27)
Coordinates: (390,27)
Coordinates: (390,27)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,29)
Coordinates: (390,29)
Coordinates: (390,29)
Coordinates: (390,30)
Coordinates: (390,30)
Coordinates: (390,30)
Coordinates: (390,30)
Coordinates: (390,31)
Coordinates: (390,31)
Coordinates: (390,32)
Coordinates: (390,32)
Coordinates: (390,32)
Coordinates: (390,33)
Coordinates: (390,33)
Coordinates: (390,33)
Coordinates: (390,33)
Coordinates: (390,33)
Coordinates: (390,34)
Coordinates: (390,34)
Coordinates: (390,34)
Coordinates: (389,34)
Coordinates: (389,35)
Coordinates: (389,36)
Coordinates: (389,36)
Coordinates: (389,36)
Coordinates: (389,37)
Coordinates: (389,36)
Coordinates: (389,37)
Coordinates: (389,37)
Coordinates: (389,37)
Coordinates: (389,37)
Coordinates: (389,38)
Coordinates: (389,38)
Coordinates: (388,38)
Coordinates: (388,38)
Coordinates: (388,38)
Coordinates: (388,38)
Coordinates: (388,39)
Coordinates: (388,39)
Coordinates: (388,39)
Coordinates: (388,39)
Coordinates: (388,39)
Coordinates: (388,40)
Coordinates: (387,40)
Coordinates: (387,40)
Coordinates: (387,40)
Coordinates: (387,40)
Coordinates: (387,40)
Coordinates: (387,40)
Coordinates: (387,40)
Coordinates: (386,41)
Coordinates: (386,41)
Coordinates: (386,41)
Coordinates: (386,41)
Coordinates: (386,41)
Coordinates: (386,41)
Coordinates: (385,41)
Coordinates: (385,41)
Coordinates: (385,41)
Coordinates: (385,41)
Coordinates: (384,42)
Coordinates: (384,42)
Coordinates: (384,42)
Coordinates: (384,42)
Coordinates: (384,42)
Coordinates: (384,42)
Coordinates: (384,42)
Coordinates: (383,42)
Coordinates: (383,42)
Coordinates: (383,42)
Coordinates: (383,42)
Coordinates: (383,43)
Coordinates: (382,43)
Coordinates: (382,43)
Coordinates: (382,43)
Coordinates: (382,43)
Coordinates: (381,43)
Coordinates: (381,43)
Coordinates: (381,43)
Coordinates: (380,43)
Coordinates: (380,44)
Coordinates: (380,44)
Coordinates: (380,44)
Coordinates: (380,44)
Coordinates: (379,44)
Coordinates: (378,44)
Coordinates: (378,44)
Coordinates: (377,44)
Coordinates: (377,44)

等等……

让我感到困惑的是:怎么会有两个连续的事件持有相同的坐标?例如,这两行:

Coordinates: (380,44)
Coordinates: (380,44)  

这基本上是说鼠标没有移动(它从 (380,44) 移动到 (380,44)),所以怎么可能有一个移动事件来启动第二行输入的处理程序?


另一个不太重要且(可能)不相关的问题:
为什么需要这条线?

gtk_widget_set_events(main_window, GDK_POINTER_MOTION_MASK);

在 Gtk+ 开发基础一书中它说:

Next, you need to add an event mask to the event box so that it knows what type of events the widget will receive. Values for the GdkEventMask enumeration that specify event masks are shown in Table 3-3. A bitwise list of GdkEventMask values can be passed to gtk_widget_set_events() if you need to set more than one.

但考虑到我们已经有了 g_signal_connect(),这个调用不是多余的吗?根据文档,这是:

Connects a GCallback function to a signal for a particular object.

The handler will be called before the default handler of the signal.

为什么一个信号需要注册两次?
一次使用 gtk_widget_set_events() 第二次使用 g_signal_connect()?

最佳答案

我尝试直接使用 xev 监视 X 服务器中的鼠标移动,xorg 似乎报告了具有相同坐标但时间戳不同的多个鼠标事件。然而,当使用键盘上的指点杆时,它并没有这样做,只能使用触控板或外接鼠标。

我的猜测是精度实际上更高,但事件是针对屏幕上的像素报告的。这可能会导致驱动程序报告比需要更多的鼠标事件。

关于C:使用 GTk+ 跟踪鼠标移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29083390/

相关文章:

c - 为什么 'man 2 open'说有两种open呢?

c - 数组 : issues declaring

python - 需要有关 GtkTextBuffer(GtkTextView)序列化/反序列化的示例/帮助

c - 如何手动编译共享dpi lib?

c++ - 在独立的 Xcode playground 中运行 c 或 c++ 代码

python - 将模型中的字段合并到一个 Gtk.TreeViewColumn 中

c - 使用 gtk_event_put 和 GdkEventButton 结构使用 GTK+ 模拟按钮点击

gtk - wxpython 保存文件对话框给出 gtk 警告

combobox - 如何使用 GTK4 使可滚动组合框可滚动?

c - 如何复制结构体指针