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

news2024/11/15 23:28:09

事件

事件处理

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_event

CFLAGS = `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_event

CFLAGS = `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!");    // label
    gtk_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_box

CFLAGS = `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.coloradmin.cn/o/1656611.html

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

相关文章

使用 YOLO 进行自定义对象检测

使用 YOLO 进行自定义对象检测 1. 创建数据集 机器是通过数据集学习的。数据集必须包含图像和标签。例如&#xff0c;让我的目标是创建一个检测坦克的系统。 我准备了从网上下载的坦克图片。然后我们需要使用第三方工具对图像进行标记&#xff0c;例如&#xff1b;LabelImg、…

SRM系统供应链库存协同提升企业服务水平

SRM系统供应链库存协同是一种以提高供应链整体效率和竞争力为目标的管理方法。它涉及到企业与供应商之间的紧密合作&#xff0c;以实现库存优化、成本降低、风险分担和灵活响应市场变化等目标。 一、SRM供应链库存协同的概念和特点 SRM供应链库存协同是指企业与供应商之间通过…

团结引擎+OpenHarmony 记录 (持续更新中)

1 TuanjiePlayerAbility.ts 中获取 content 引用 globalThis.AbilityContext 在 TuanjiePlayerAbility.ts 中是可以获取到的 但是在 tslib 或者中 globalThis.AbilityContext 是无法获取到的GetFromGlobalThis(‘AbilityContext’); 同样 在 TuanjiePlayerAbility.ts 中是可以…

文献速递:深度学习医学影像心脏疾病检测与诊断--基于深度学习的PET图像重建与运动估计

Title 题目 Deep Learning Based Joint PET Image Reconstruction and Motion Estimation 基于深度学习的PET图像重建与运动估计 01 文献速递介绍 正电子发射断层扫描&#xff08;PET&#xff09;成像是一种非侵入性成像技术&#xff0c;通过使用放射性示踪剂在活体内可视化…

UE4_摄像机_使用摄像机的技巧

学习笔记&#xff0c;不喜勿喷&#xff01;祝愿生活越来越好&#xff01; 知识点&#xff1a; a.相机跟随。 b.相机抖动。 c.摄像机移动 d.四元数插值&#xff08;保证正确旋转方向&#xff09;。 e.相机注视跟踪。 1、新建关卡序列&#xff0c;并给小车添加动画。 2、创…

C++奇迹之旅:string类接口详解(上)

文章目录 &#x1f4dd;为什么学习string类&#xff1f;&#x1f309; C语言中的字符串&#x1f309;string考察 &#x1f320;标准库中的string类&#x1f309;string类的常用接口说明&#x1f320;string类对象的常见构造 &#x1f6a9;总结 &#x1f4dd;为什么学习string类…

Unity Navigation 入门(新版)

概述 在游戏的制作过程中&#xff0c;寻路功能一定是非常重要的部分&#xff0c;他可以为主角寻路&#xff0c;也可以运用到敌人追击等&#xff0c;相比于自己实现的难度&#xff0c;使用寻路组件就显得简单的多&#xff0c;那接下来就开始学习这部分的内容吧 1.安装AI Naviga…

vue3打开页面后文本框自动获得焦点

字符串写法 <script setup> import { ref, onMounted } from vue import ./index.cssconst input ref(null)onMounted(() > {input.value.focus() }) </script><template><div class"m-home-wrap"><input ref"input" />…

[NSSRound#1 Basic]basic_check

[NSSRound#1 Basic]basic_check 开题什么都没有&#xff0c;常规信息搜集也无效 发现题目允许PUT的两种做法&#xff1a; 1、 CURL的OPTIONS请求方法查看允许的请求方式 curl -v -X OPTIONS http://node4.anna.nssctf.cn:28545/index.php2、 kali自带的nikto工具扫描网址 Nik…

已经有 Prometheus 了,还需要夜莺?

谈起当下监控&#xff0c;Prometheus 无疑是最火的项目&#xff0c;如果只是监控机器、网络设备&#xff0c;Zabbix 尚可一战&#xff0c;如果既要监控设备又要监控应用程序、Kubernetes 等基础设施&#xff0c;Prometheus 就是最佳选择。甚至有些开源项目&#xff0c;已经内置…

css z-Index 详解--子元素盖在父元素的兄弟元素上

前置知识 1、z-index 只有在定位元素上才会生效&#xff08;即非static定位的元素上&#xff09; 2、同级元素&#xff0c;无论是z-index 相同还是没设置。后面的元素层级比前面 3、元素上有 transform 属性 z-index 会失效 dom结构如下 // dom部分 <div><div id&quo…

数学建模资料|历年数维杯数学建模竞赛真题及获奖论文汇总

2024年第九届数维杯大学生数学建模挑战赛&#xff1a;2024年5月10日08:00-5月13日09:00举行&#xff0c;为了更好的帮助参赛同学了解竞赛的赛制及赛题特点&#xff0c;数乐君今天给大家整理了历年数维杯国赛真题及优秀论文&#xff0c;方便同学们赛前巩固训练&#xff0c;掌握解…

私人健身教练预约管理小程序开发源码现成案例(小程序+APP+H5 源码部署)

一、私人健身教练预约管理系统-环境介绍 1.1 私人健身教练预约管理系统-运行环境 开发语言&#xff1a;PHP 数据库&#xff1a;MySQL 系统架构&#xff1a;TP 后端&#xff1a;SpringBoot 前端&#xff1a;Vue 2. 私人健身教练预约管理系统-系统介绍。 2.1私人健身教练预约管…

实在Agent智能体:引领智能自动化新纪元

在数字化转型的浪潮中&#xff0c;实在智能科技有限公司凭借其前沿技术&#xff0c;推出了实在Agent智能体——一款革命性的超自动化智能体。它不仅代表了人工智能技术的新高度&#xff0c;更预示着未来工作方式的变革。 什么是实在Agent智能体&#xff1f; 实在Agent智能体是…

拼多多投产比怎么计算?

拼多多投产比&#xff08;ROI&#xff09;的计算公式为&#xff1a;ROI 成交金额 / 花费 100%。也可以简单理解为&#xff1a;ROI 点击量 * 转化率 * 客单价 / (点击量 * 平均点击花费)。 拼多多推广可以使用3an推客。3an推客&#xff08;CPS模式&#xff09;给商家提供的营…

acronym 数据集

raise gl.ContextException(Could not create GL context) conda install -c conda-forge libstdcxx-ng ImportError: trimesh.viewer.windowed requires pip install "pyglet<2" pip install pyglet1.5.28github上的示例 3D 场景下的 RGBD Mask

Fortinet的安全愿景SASO概述

FTNT SASE的独特方法&#xff0c;使其成为一家适应性极强的厂商&#xff0c;能够应对不断变化的网络和网络安全环境。FTNT开发了一种名为Secure Access Service Omni&#xff08;SASO&#xff09;的变体&#xff0c;以更准确地反映FTNT在融合网络和安全功能方面的实力。我们预计…

老牌Git客户端 mac软件 SmartGit 汉化教程 及安装教程

SmartGit for Mac一款 Git 版本控制系统的图形化客户端程序&#xff0c;它能在您的工作上满足您的需求&#xff0c;smartgit是一个企业级的Git、Mercurial、以及Subversion图形化客户端软件&#xff0c;功能非常强大&#xff0c;它可以简单快速的实现Git及Mercurial中的版本控制…

SaaS、PaaS、IaaS、DaaS功能区别、优缺点以及关联简述

目前主流的IaaS、PaaS和SaaS产品 简述应用方案 这里借用汽车的例子对IaaS、PaaS、SaaS的解释进一步阐述三者的区别。 假设你需要出去外出使用交通工具&#xff0c;我们有四种的方案&#xff1a; On-premise&#xff08;本地部署服务&#xff09; 自己开车&#xff0c;需要维护…

容器化管理SpringBoot项目:在用jar包制作镜像的时候遇到的错误记录

在容器化管理SpringBoot项目&#xff0c;进行到“用jar包制作镜像”一步时&#xff0c;遇到的error真的是一环接着一环&#xff0c;这里就记录一下&#xff0c;一套流程下来遇到的error&#xff0c;以及一些我的解决方法&#xff1a; ERROR: "docker buildx build" r…