简体   繁体   English

如何在GTK +中检测鼠标点击图像?

[英]How to detect mouse click over an image in GTK+?

I'm working on a project in C using gtk+ 2.0. 我正在使用gtk + 2.0在C项目中工作。

I must check if the user has pressed left click on a image. 我必须检查用户是否按下左键单击图像。 I thought to call a function when left click is pressed and to get the position of the mouse, but how can I do that? 我想在按下左键时调用一个函数来获取鼠标的位置,但是我怎么能这样做呢?

I hope I can assume you know how to connect an event to a widget, but if not: Here's a previous answer of mine that demonstrates how to do just that. 我希望我可以假设您知道如何将事件连接到窗口小部件,但如果没有:这是我之前的答案,演示了如何做到这一点。

g_signal_connect for right mouse click? g_signal_connect用于鼠标右键单击?

As you can see there the event is passed as a GdkEventButton * ( event from now on). 正如您所看到的那样,事件作为GdkEventButton *传递(从现在开始的event )。 This struct has the member fields that you are after: event->x and event->y both are gdouble fields. 这个结构有你以后的成员字段: gdouble event->xgdouble event->y都是gdouble字段。

Anyway, @unwind is right. 无论如何,@ unwind是对的。 As the GTK docs clearly state: 正如GTK文档明确指出:

GtkImage is a “no window” widget (has no GdkWindow of its own), so by default does not receive events. GtkImage是一个“无窗口”小部件(它没有自己的GdkWindow),因此默认情况下不接收事件。 If you want to receive events on the image, such as button clicks, place the image inside a GtkEventBox, then connect to the event signals on the event box. 如果要在图像上接收事件(例如按钮单击),请将图像放在GtkEventBox中,然后连接到事件框上的事件信号。

GtkImage is not the only "windowless" widget, BTW. GtkImage不是唯一的“无窗口”小部件,BTW。 GtkLabel , for example, requires a similar approach if you want to handle clicks on a label. 例如,如果您想要处理标签上的点击, GtkLabel需要类似的方法。 Anyway: More info here . 无论如何: 这里有更多信息
The man page then continues with a full code example of how to handle clicks on a GtkImage widget. 然后,手册页继续提供有关如何处理GtkImage小部件上的点击的完整代码示例 Just look for the title "Handling button press events on a GtkImage." 只需查看标题“处理GtkImage上的按钮按钮事件”。 for the full explanation, but here's the code in case the link breaks: 有关完整的解释,但这里是链接中断的代码:

static gboolean
button_press_callback (GtkWidget      *event_box,
                       GdkEventButton *event,
                       gpointer        data)
{
    g_print ("Event box clicked at coordinates %f,%f\n",
         event->x, event->y);

    // Returning TRUE means we handled the event, so the signal
    // emission should be stopped (don’t call any further callbacks
    // that may be connected). Return FALSE to continue invoking callbacks.
    return TRUE;
}

static GtkWidget*
create_image (void)
{
    GtkWidget *image;
    GtkWidget *event_box;

    image = gtk_image_new_from_file ("myfile.png");

    event_box = gtk_event_box_new ();

    gtk_container_add (GTK_CONTAINER (event_box), image);

    g_signal_connect (G_OBJECT (event_box),
                  "button_press_event",
                  G_CALLBACK (button_press_callback),
                  image);

    return image;
}

The problem is that the GtkImage widget which is used to show an image in GTK+ does not generate events. 问题是用于在GTK +中显示图像的GtkImage小部件不会生成事件。

It's a "nowindow" widget, meaning that it's a passive container, which is used to display information and not to interact with the user. 它是一个“nowindow”小部件,意味着它是一个被动容器,用于显示信息而不与用户交互。

You can fix that by wrapping the image in a GtkEventBox , which will add event support. 您可以通过将图像包装在GtkEventBox中来解决这个问题 ,这将添加事件支持。

In GTK you can use the button-pressed-event gtk widget to do this 在GTK中,您可以使用按钮按下事件 gtk小部件来执行此操作

In pure c, from Programming Simplified 在纯c中,来自Programming Simplified

#include<graphics.h>
#include<conio.h>
#include<stdio.h>
#include<dos.h>

int initmouse();
void showmouseptr();
void hidemouseptr();
void getmousepos(int*,int*,int*);

union REGS i, o;

main()
{
   int gd = DETECT, gm, status, button, x, y, tempx, tempy;
   char array[50];

   initgraph(&gd,&gm,"C:\\TC\\BGI");
   settextstyle(DEFAULT_FONT,0,2);

   status = initmouse();

   if ( status == 0 )
      printf("Mouse support not available.\n");
   else
   {
      showmouseptr();

      getmousepos(&button,&x,&y);

      tempx = x;
      tempy = y;

      while(!kbhit())
      {
         getmousepos(&button,&x,&y);

         if( x == tempx && y == tempy )
         {}
         else
         {
            cleardevice();
            sprintf(array,"X = %d, Y = %d",x,y);
            outtext(array);
            tempx = x;
            tempy = y;
         }
      }
   }

   getch();
   return 0;
}

int initmouse()
{
   i.x.ax = 0;
   int86(0X33,&i,&o);
   return ( o.x.ax );
}

void showmouseptr()
{
   i.x.ax = 1;
   int86(0X33,&i,&o);
}

void getmousepos(int *button, int *x, int *y)
{
   i.x.ax = 3;
   int86(0X33,&i,&o);

   *button = o.x.bx;
   *x = o.x.cx;
   *y = o.x.dx;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM