【问题标题】:How do I set the mouse cursor to cross hair over a GtkDrawingArea?如何将鼠标光标设置为在 GtkDrawingArea 上交叉?
【发布时间】:2017-05-01 00:16:11
【问题描述】:

在 GTK3 中,当鼠标悬停在 GtkWidget(本例中为 GtkDrawingArea)上时,如何将鼠标光标设置为十字准线?

【问题讨论】:

    标签: c mouseover gtk3


    【解决方案1】:

    首先,您必须将GtkDrawingArea 小部件告诉use a backing window,以便接收事件:

    gtk_widget_set_has_window (GTK_WIDGET (darea), TRUE);
    

    那你必须告诉它which events you wish to subscribe to;在这种情况下,您需要交叉事件,以便接收指针进入和离开小部件的通知:

    int crossing_mask = GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
    gtk_widget_add_events (GTK_WIDGET (darea), crossing_mask);
    

    此时,您可以连接到GtkWidget::enter-notify-eventGtkWidget::leave-notify-event 信号:

    g_signal_connect (darea, "enter-notify-event", G_CALLBACK (on_crossing), NULL);
    g_signal_connect (darea, "leave-notify-event", G_CALLBACK (on_crossing), NULL);
    

    如果需要,您可以使用两个单独的信号处理程序,但除非您在其中执行一些复杂的操作,否则代码将几乎相同。

    on_crossing() 处理程序将如下所示:

    static gboolean
    on_crossing (GtkWidget *darea, GdkEventCrossing *event)
    {
      switch (gdk_event_get_event_type (event))
        {
        case GDK_ENTER_NOTIFY:
          // Do something on enter
          break;
    
        case GDK_LEAVE_NOTIFY:
          // Do something on leave
          break;
        }
    }
    

    现在您已根据事件类型指定要使用的光标。 GTK+ 使用相同的游标名称as CSS does;您需要使用one of those names 创建a cursor instance,然后将其关联到绘图区域小部件使用的GdkWindow

    // Get the display server connection
    GdkDisplay *display = gtk_widget_get_display (darea);
    GdkCursor *cursor;
    
    switch (gdk_event_get_event_type (event))
      {
      case GDK_ENTER_NOTIFY:
        cursor = gdk_cursor_new_from_name (display, "crosshair");
        break;
      case GDK_ENTER_NOTIFY:
        cursor = gdk_cursor_new_from_name (display, "default");
        break;
      }
    
    // Assign the cursor to the window
    gdk_window_set_cursor (gtk_widget_get_window (darea), cursor);
    
    // Release the reference on the cursor
    g_object_unref (cursor);
    

    【讨论】:

    • 感谢您的详细解答!请查看我的后续问题:stackoverflow.com/questions/43723638/…
    • 'gtk_widget_set_has_window()' 的文档说:“这个函数只能由小部件实现调用,它们应该在它们的 init() 函数中调用它。” .... 将eventbox_box 作为drawing_area 的容器还不够吗?
    • 是的,你也可以使用 GtkEventBox,然后在其中添加 GtkDrawingArea;或者您可以继承 GtkDrawingArea 并在您自己的新类型的实例初始化函数中调用 gtk_widget_set_has_window() 。使用现有 API 有更多方法可以做到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-14
    • 2018-04-11
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 2011-12-19
    相关资源
    最近更新 更多