GtkButton事件处理、事件的捕获、鼠标事件等

事件

事件处理

GTK+ 所提供的工具库与其应用程序都是基于事件触发机制来管理, 所有的应用程序都是基于事件驱动

如果没有事件发生, 应用程序将处于等待状态, 不会执行任何操作, 一旦事件发生, 将根据不同的事件做出相应的处理。

GTK+中,当一个事件发生时, 程序就会通过发送一个信号来通知应用程序执行相关的操作, 即调用与这一信号进行连接的回调函数, 来完成一次由事件所触发的行动。

事件的捕获

/* 设置控件捕获相应的事件* events: 事件类型, 它是 GdkEventMask 的枚举常量* GDK_BUTTON_PRESS_MASK: 鼠标点击* GDK_BUTTON_RELEASE_MASK: 鼠标释放* GDK_BUTTON_MOTION_MASK: 鼠标移动* GDK_KEY_PRESS_MASK: 键盘按下* GDK_ENTER_NOTIFY_MASK: 进入控件区域*/
void gtk_widget_add_events(GtkWidget *widget, gint events );

鼠标事件

主窗口默认不接收鼠标事件, 需要手动添加

触发鼠标点击事件的信号: button-press-event

触发鼠标释放事件的信号: button-release-event

// 回调函数
// event->x, event->y: 得到点击坐标值
// event->button: 鼠标哪个键按下
// event->type: 是否双击
gboolean callback( GtkWidget *widget, GdkEventButton *event, gpointer data );

触发鼠标移动事件的信号: motion-notify-event

// 回调函数
// event->x, event->y: 得到移动的坐标值
gboolean callback( GtkWidget *widget, GdkEventMotion *event, gpointer data );

栗子 : mouse_event.c

#include <gtk/gtk.h>    // 头文件// 鼠标点击事件处理函数
gboolean deal_mouse_press(GtkWidget *widget, GdkEventButton *event, gpointer data)
{// 判断鼠标点击的类型switch(event->button){case 1:printf("Left Button!!\n");break;case 2:printf("Middle Button!!\n");break;case 3:printf("Right Button!!\n");break;default:printf("Unknown Button!!\n");}if(event->type == GDK_2BUTTON_PRESS){printf("double click\n");}// 获得点击的坐标值,距离窗口左顶点gint i = event->x;gint j = event->y;printf("press_x = %d, press_y = %d\n", i, j);return TRUE;
}// 鼠标移动事件(点击鼠标任何键)的处理函数
gboolean deal_motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
{// 获得移动鼠标的坐标值,距离窗口左顶点gint i = event->x;gint j = event->y;printf("motion_x = %d, motion_y = %d\n", i, j);return TRUE;
}int main( int argc,char *argv[] )
{gtk_init(&argc, &argv);        // 初始化// 创建顶层窗口GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);// 设置窗口的标题gtk_window_set_title(GTK_WINDOW(window), "cpucode mouse_event");// 设置窗口在显示器中的位置为居中gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);// 设置窗口的最小大小gtk_widget_set_size_request(window, 400, 300);// "destroy" 和 gtk_main_quit 连接g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);// 窗口接收鼠标事件// GDK_BUTTON_PRESS_MASK :鼠标点击事件// GDK_BUTTON_MOTION_MASK :按住鼠标移动事件gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_MOTION_MASK);// "button-press-event" 与 deal_mouse_event 连接,鼠标点击事件g_signal_connect(window, "button-press-event", G_CALLBACK(deal_mouse_press), NULL);// "motion-notify-event" 与 deal_motion_notify_event 连接,按住鼠标移动事件g_signal_connect(window, "motion-notify-event", G_CALLBACK(deal_motion_notify_event), NULL);gtk_widget_show_all(window);    // 显示窗口全部控件gtk_main();        // 主事件循环return 0;
}

Makefile :

CC = gcc  
MAINC = mouse_event.c
EXEC = mouse_eventCFLAGS = `pkg-config --cflags --libs gtk+-2.0`main:  $(CC)  $(MAINC)  -o $(EXEC) $(CFLAGS)
clean:rm $(EXEC) -rf

键盘事件

主窗口默认就能接收键盘事件, 其中的键值定义在 gtk-2.0/gdk/gdkkeysyms-compat.h 文件里

触发键盘按下事件的信号: key-press-event

触发键盘释放事件的信号: key-release-event

// 回调函数
// event->keyval: 获取按下(释放)键盘键值
gboolean callback( GtkWidget *widget, GdkEventKey *event, gpointer data );

栗子 : key_event.c

#include <gtk/gtk.h>    // 头文件
#include <gdk/gdkkeysyms.h>    //键盘头文件// 键盘按下事件处理函数
gboolean deal_key_press(GtkWidget *widget, GdkEventKey  *event, gpointer data)
{switch(event->keyval){    // 键盘键值类型case GDK_Up:g_print("Up\n");break;case GDK_Left:g_print("Left\n");break;case GDK_Right:g_print("Right\n");break;case GDK_Down:g_print("Down\n");break;default:printf("Unknown Button!!\n");}int key = event->keyval; // 获取键盘键值类型g_print("keyval = %d\n", key);return TRUE;
}int main( int argc, char *argv[] )
{gtk_init(&argc, &argv);        // 初始化// 创建顶层窗口GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);// 设置窗口的标题gtk_window_set_title(GTK_WINDOW(window), "cpucode mouse_event");// 设置窗口在显示器中的位置为居中gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);// 设置窗口的最小大小gtk_widget_set_size_request(window, 400, 300);// "destroy" 和 gtk_main_quit 连接g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);// "key-press-event" 与 deal_key_press 连接g_signal_connect(window, "key-press-event", G_CALLBACK(deal_key_press), NULL);gtk_widget_show_all(window);    // 显示窗口全部控件gtk_main();        // 主事件循环return 0;
}

Makefile :

CC = gcc  
MAINC = key_event.c
EXEC = key_eventCFLAGS = `pkg-config --cflags --libs gtk+-2.0`main:  $(CC)  $(MAINC)  -o $(EXEC) $(CFLAGS)
clean:rm $(EXEC) -rf

事件盒子(GtkEventBox)

有些控件( GtkLabel ), 不响应 GDK 事件。 GTK+通过事件盒子给控件提供一个 GDK 窗口来捕获事件。

//事件盒子的创建
GtkWidget *gtk_event_box_new(void);
//添加控件到事件盒子里
void gtk_container_add(GtkContainer *container, GtkWidget *widget );

栗子 : event_box.c

/* 通过使用事件盒子,连接 button-press-event 信号到 GtkLabel。* 当标签被双击时,标签中的文本会根据当前的状态改变。* 当单击事件发生时,什么都不会发生,尽管在本例中这个信号也被发出了。*/#include <gtk/gtk.h>static gboolean button_pressed(GtkWidget*, GdkEventButton*, GtkLabel*); // 函数的声明int main( int argc, char *argv[] )
{gtk_init(&argc, &argv);GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);    // 主窗口gtk_window_set_title(GTK_WINDOW(window), "cpucode Event Box");        // 标题gtk_container_set_border_width(GTK_CONTAINER(window), 10);gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); // 居中显示gtk_widget_set_size_request(window, 200, 50);                     // 最小大小g_signal_connect(window, "destroy",G_CALLBACK(gtk_main_quit), NULL ); GtkWidget *eventbox = gtk_event_box_new();                // 事件盒子的创建gtk_widget_set_events(eventbox, GDK_BUTTON_PRESS_MASK); // 捕获鼠标点击事件gtk_container_add( GTK_CONTAINER(window), eventbox );    // 事件盒子放入窗口GtkWidget *label = gtk_label_new("Double-Click Me!");    // labelgtk_container_add( GTK_CONTAINER(eventbox), label );    // label放入事件盒子里g_signal_connect(eventbox, "button_press_event", G_CALLBACK(button_pressed), (gpointer)label);gtk_widget_show_all(window);    // 显示所有控件gtk_main();return 0;
}/* This is called every time a button-press event occurs on the GtkEventBox. */
static gboolean button_pressed( GtkWidget *eventbox, GdkEventButton *event, GtkLabel *label )
{if (event->type == GDK_2BUTTON_PRESS){const gchar *text = gtk_label_get_text(label);if( text[0] == 'D' ){gtk_label_set_text(label, "I Was Double-Clicked!");}else{gtk_label_set_text(label, "Double-Click Me Again!");}}return FALSE;
}

Makefile

CC = gcc  
MAINC = event_box.c
EXEC = event_boxCFLAGS = `pkg-config --cflags --libs gtk+-2.0`main:  $(CC)  $(MAINC)  -o $(EXEC) $(CFLAGS)
clean:rm $(EXEC) -rf

  • @由于个人水平有限, 难免有些错误, 还请指点:
  • @Author: cpu_code
  • @Date: 2020-08-06 16:51:19
  • @LastEditTime: 2020-08-06 18:27:18
  • @FilePath: \notes\GTK\Event_handling.md
  • @Gitee: https://gitee.com/cpu_code
  • @Github: https://github.com/CPU-Code
  • @CSDN: https://blog.csdn.net/qq_44226094
  • @Gitbook: https://923992029.gitbook.io/cpucode/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/9287.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Offer必备算法37_记忆化搜索_五道力扣题详解(由易到难)

目录 记忆化搜索概念和使用场景 ①力扣509. 斐波那契数 解析代码1_循环 解析代码2_暴搜递归 解析代码3_记忆化搜索 解析代码4_动态规划 ②力扣62. 不同路径 解析代码1_暴搜递归&#xff08;超时&#xff09; 解析代码2_记忆化搜索 解析代码3_动态规划 ③力扣300. 最…

Java12基础(Package包 作用域 String字符串)

目录 一. Package包 import关键字 命名规范 二. 作用域 三. String字符串(进阶) 创建方式: 内存情况: 1. 字符串的搜索 2. trim()方法 3. 替换字符串 4. 分割字符串 5. 拼接字符串 6. 格式化字符串 7. 类型转换 8. 转换为char[ ]字符数组 9. 字符编码 10. Str…

Navicat导入sql报错[Err] 1046 - No database selected

Navicat导入sql报错[Err] 1046 - No database selected ​ 今天系统重装了&#xff0c;就很完蛋。所有东西都重新下载安装。向Navicat导入sql的时候导入失败&#xff1a; 报错[Err] 1046 - No database selected。我很疑惑地又导了几次。当然又全都失败. 错误造成原因&#x…

ardupilot的固定翼飞行模式

飞行模式 APM所有的飞行模式都在对应的机型的文件夹下的mode.h里面有定义,针对于不同的模型,功能函数在基类中Mode中都是以纯虚函数实现了, 然后在继承的子类中重新实现它,以实现多态。 takeoff模式 参见网址在 ArduPlane 4.0 及更高版本中,自动起飞本身也是一种模式(…

Redis持久化策略——Java全栈知识(17)

Redis持久化 1、Redis 持久化的三种方式 1、RDB&#xff1a; 以快照的方式将此刻 Redis 中的数据以二进制的文件形式保存在磁盘中。 RDB 的优点是&#xff1a;快照文件小、恢复速度快&#xff0c;适合做备份和灾难恢复。 RDB 的缺点是&#xff1a;定期更新可能会丢数据&#…

20K薪资要什么水平?来看看25岁测试工程师的面试过程…_测试工程师薪资20k(2)

既有适合小白学习的零基础资料&#xff0c;也有适合3年以上经验的小伙伴深入学习提升的进阶课程&#xff0c;涵盖了95%以上软件测试知识点&#xff0c;真正体系化&#xff01; 由于文件比较多&#xff0c;这里只是将部分目录截图出来&#xff0c;全套包含大厂面经、学习笔记、…

阿里云最新重磅发布:通义千问2.5模型更强、5到10行代码搭建企业RAG应用、代码助手通义灵码推企业版

速览&#xff1a; 5月9日阿里云举办“阿里云AI智领者峰会”&#xff0c;会上发布一系列重磅产品&#xff0c;通义千问模型性能更强&#xff0c;通义灵码、阿里云百炼平台、通义千问App等均有重要信息发布。 会上阿里云发布正式发布通义千问2.5&#xff0c;中文性能全面赶超GPT-…

我们的小程序每天早上都白屏,真相是。。。

大家好&#xff0c;我是程序员鱼皮。最近我们在内测一款面试刷题小程序&#xff0c;没错&#xff0c;就是之前倒下的 “面试鸭”&#xff01; 在我们的内测交流群中&#xff0c;每天早上都会有同学反馈&#xff1a;打开小程序空白&#xff0c;没任何内容且登录不上。 然后过了…

PT:fix_eco_power用法

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 ICC2中没有直接修leakage/power的命令,需要在scenario status中设置leakage_power和dynamic_power的开关,结合place_opt/clock_opt.flow.enable_power true来使用。 innovus中专门的命令可以去优…

单单单单单の刁队列

在数据结构的学习中&#xff0c;队列是一种常用的线性数据结构&#xff0c;它遵循先进先出&#xff08;FIFO&#xff09;的原则。而单调队列是队列的一种变体&#xff0c;它在特定条件下保证了队列中的元素具有某种单调性质&#xff0c;例如单调递增或单调递减。单调队列在处理…

游戏辅助 -- 三种分析角色坐标方法(CE、xdbg、龙龙遍历工具)

所用工具下载地址&#xff1a; https://pan.quark.cn/s/d54e7cdc55e6 在上次课程中&#xff0c;我们成功获取了人物对象的基址&#xff1a;[[[0xd75db8]1C]28]&#xff0c;而人物血量的地址则是基址再加上偏移量278。 接下来&#xff0c;我们需要执行以下步骤来进一步操作&a…

新版security demo(二)前端

写这篇博客&#xff0c;刚好换了台电脑&#xff0c;那就借着这个demo复习下VUE环境的搭建。 一、前端项目搭建 1、安装node 官网下载安装即可。 2、安装脚手架 npm install -g vue-cli 使用脚手架搭建一个demo前端项目 vue init webpack 项目名称 3、安装依赖 这里安装…

【OpenHarmony 实战开发】 做一个 loading加载动画

本篇文章介绍了如何实现一个简单的 loading 加载动画&#xff0c;并且在文末提供了一个 demo 工程供读者下载学习。作为一个 OpenHarmony 南向开发者&#xff0c;接触北向应用开发并不多。北向开发 ArkUI 老是改来改去&#xff0c;对笔者这样的入门选手来说学习成本其实非常大&…

【每日力扣】98. 验证二叉搜索树 与 108. 将有序数组转换为二叉搜索树

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害 98. 验证二叉搜索树 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&a…

【C++】适配器模式

文章目录 前言 1. 适配器的介绍2. 仿函数2.1 sort函数的模板参数2.2 priority_queue类的模板参数 3. priority_queue模拟实现3. stack & queue 模拟实现3.1 deque的介绍3.2 deque的优点与缺陷3.3 STL标准库中对于stack和queue的模拟实现 前言 C中的适配器是一种设计模式&am…

物联网实战--平台篇之(四)账户后台交互

目录 一、交互逻辑 二、请求验证码 三、帐号注册 四、帐号/验证码登录 五、重置密码 本项目的交流QQ群:701889554 物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html 物联网实战--驱动篇https://blog.csdn.net/ypp240124016/category_12631…

线程安全的概念及原因

1.观察线程不安全 public class ThreadDemo {static class Counter {public int count 0;void increase() {count;}}public static void main(String[] args) throws InterruptedException {final Counter counter new Counter();Thread t1 new Thread(() -> {for (int …

进一步分析并彻底解决 Flink container exit 143 问题

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

AlibabaCloud微服务下的链路追踪系统实战详解

&#x1f680; 作者 &#xff1a;“二当家-小D” &#x1f680; 博主简介&#xff1a;⭐前荔枝FM架构师、阿里资深工程师||曾任职于阿里巴巴担任多个项目负责人&#xff0c;8年开发架构经验&#xff0c;精通java,擅长分布式高并发架构,自动化压力测试&#xff0c;微服务容器化k…

如何利用AI技术提升内容生产的效率和质量

目录 前言1 自动化内容生成1.1 文章生成1.2 视频制作1.3 音频合成 2 内容分发与推广2.1 智能内容推荐2.2 社交媒体管理 3 内容分析与优化3.1 用户反馈分析3.2 内容效果评估 结语 前言 在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;技术对内容生产、分发和优…