gtk鼠标事件之画图程序

⌚Time: 2022-07-14 21:12:43

👨‍💻Author: Jack Ge

gtk窗口默认不支持鼠标事件,需要通过gtk_widget_add_events函数手动添加(鼠标移动和释放事件)。


gtk_widget_add_events(window,GDK_BUTTON_MOTION_MASK|GDK_BUTTON_RELEASE_MASK);

鼠标移动事件回调函数:


void callback_func(GtkWidget *widget,GdkEventMotion *event,gpointer);

鼠标释放事件回调函数:


void callback_func(GtkWidget *widget,GdkEventButton *event,gpointer data);

鼠标画线实现思路:

定义全局变量xOld、yOld,用于储存旧鼠标位置,当鼠标移动时,使用criao对旧鼠标位置与当前鼠标位置进行连线,并且不断的设置当前鼠标为旧鼠标位置。实现动态的鼠标画线。

demo.c


#include <gtk/gtk.h>

#include <stdio.h>

//rand()

#include <stdlib.h>

#define X_WIDTH 600

#define X_HEIGHT 400

int xOld = 0;

int yOld = 0;

//鼠标移动回调函数

void mouse_move(GtkWidget *widget,GdkEventMotion *event,gpointer data){



    cairo_t *cr;

    cr = gdk_cairo_create (widget->window);

    //如果x位置为0,让他等于当前鼠标x位置(如果是初始化的值,相当于从当前鼠标开始绘制)

    if(xOld == 0){

        xOld = (int)event->x;

    }

    if(yOld == 0){

        yOld = (int)event->y;

    }

    //设置随机颜色

    cairo_set_source_rgb(cr,(float)(rand()%100)/100,(float)(rand()%100)/100,(float)(rand()%100)/100);

    //设置线段粗细

    cairo_set_line_width(cr,1);

    //画线

    cairo_move_to(cr,xOld, yOld);

    cairo_line_to(cr,(int)event->x, (int)event->y); 

    cairo_stroke(cr);//clear line path

    //更新旧鼠标位置

    xOld = (int)event->x;

    yOld = (int)event->y;



    printf("%d %d\n",(int)event->x,(int)event->y);

}

//鼠标释放回调函数

void mouse_release(GtkWidget *widget,GdkEventButton *event,gpointer data){

    //鼠标释放,清空旧位置,避免下次任意位置点击鼠标与当前位置连成直线

    xOld = 0;

    yOld = 0;

}

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





    srand((unsigned int)time(0));

    GtkWidget *window;

    gtk_init(&argc,&argv);

 

    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);

    gtk_window_set_title(GTK_WINDOW(window),"Demo");

    gtk_window_set_default_size(GTK_WINDOW(window),X_WIDTH,X_HEIGHT);



    g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);

    //添加鼠标事件支持

    gtk_widget_add_events(window,GDK_BUTTON_MOTION_MASK|GDK_BUTTON_RELEASE_MASK);

    //gtk_widget_add_events(window,GDK_ENTER_NOTIFY_MASK);

    //关联事件的回调函数

    g_signal_connect(window,"motion-notify-event",G_CALLBACK(mouse_move),NULL);

    g_signal_connect(window,"button-release-event",G_CALLBACK(mouse_release),NULL);

    

    gtk_widget_show_all(window);

    //设置窗口可绘制

    gtk_widget_set_app_paintable(window,true);

    gtk_main();

 

    return 0;

}