gtk窗口默认不支持鼠标事件,需要通过gtk_widget_add_events函数手动添加(鼠标移动和释放事件)。
鼠标移动事件回调函数:
鼠标释放事件回调函数:
鼠标画线实现思路:
定义全局变量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;
}
