C++GUI之wxWidgets(10)-编写应用涉及的类和方法(5)-事件处理(4)

news2024/11/14 6:25:11

目录

  • 自定义事件
    • AddPendingEvent()
    • QueueEvent()
    • PushEventHandler()
    • ProcessEvent()
    • wxCommandEvent与新的事件类型一起使用

自定义事件

AddPendingEvent()


virtual void wxEvtHandler::AddPendingEvent 	( 	const wxEvent &  event	) 	

发布要稍后处理的事件。

此函数类似于QueueEvent(),但不能用于从工作线程中发布具有wxString字段的事件对象(即实际上大多数事件对象)的事件,因为不安全地使用了相同的wxString对象,这是因为原始事件对象中的wxString字段及其内部由此函数生成的副本在内部共享相同的字符串缓冲区。使用QueueEvent()可以避免这种情况。

事件的副本由函数生成,因此一旦函数返回,就可以删除原始事件(通常在堆栈上创建原始事件)。这要求wxEvent::Clone()方法由事件实现,以便在处理之前可以复制和存储它。

QueueEvent()

virtual void wxEvtHandler::QueueEvent 	( 	wxEvent *  	event	) 	

队列事件以供稍后处理。

此方法类似于ProcessEvent(),但后者是同步的,即在函数返回之前立即处理事件,此方法是异步的,并立即返回,而事件将在稍后的时间(通常在下一个事件循环迭代期间)处理。

另一个重要的区别是,该方法拥有事件参数的所有权,即它将自己删除它。这意味着应该在堆上分配事件,并且在函数返回后不能再使用指针(因为它可以随时删除)。

QueueEvent()可用于从工作线程到主线程的线程间通信,它在内部使用锁定,并通过确保调用线程不再使用事件对象来避免AddPendingEvent()文档中提到的问题,这是安全的。仍应注意避免此对象的某些字段被它使用,特别是事件对象的任何wxString成员都不能是另一个wxString对象的浅层副本,因为这将导致它们在幕后仍然使用相同的字符串缓冲区。例如:

void FunctionInAWorkerThread(const wxString& str)
{
    wxCommandEvent* evt = new wxCommandEvent;
 
    // NOT evt->SetString(str) as this would be a shallow copy
    evt->SetString(str.c_str()); // make a deep copy
 
    wxTheApp->QueueEvent( evt );
}

请注意,可以使用wxThreadEvent而不是wxCommandEvent来避免此问题:

void FunctionInAWorkerThread(const wxString& str)
{
    wxThreadEvent evt;
    evt.SetString(str);
 
    // wxThreadEvent::Clone() makes sure that the internal wxString
    // member is not shared by other wxString instances:
    wxTheApp->QueueEvent( evt.Clone() );
}

最后注意,如果事件循环当前处于空闲状态,该方法会通过调用wxWakeUpIdle()自动唤醒事件循环,因此在使用它时无需手动执行。

参数

要添加到挂起事件队列的事件事件。

PushEventHandler()

void wxWindow::PushEventHandler 	( 	wxEvtHandler *  	handler	) 	

将此事件处理程序推送到窗口的事件堆栈上。

事件处理程序是能够处理发送到窗口的事件的对象。默认情况下,窗口是它自己的事件处理程序,但应用程序可能希望替换另一个,例如,以允许对各种不同的窗口类集中实现事件处理。

wxWindow::PushEventHandler允许应用程序设置事件处理程序堆栈,其中未由一个事件处理程序处理的事件被传递给链中的下一个事件。

如果您有两个事件处理程序A和B以及一个wxWindow实例W,并且您调用:

W->PushEventHandler(A);
W->PushEventHandler(B);

您将遇到以下情况:
在这里插入图片描述

注意,可以使用wxWindow::PopEventHandler删除事件处理程序。

参数

handler指定要推送的处理程序。它不能是wxEvtHandler链的一部分;如果未取消链接,断言将失败(请参阅wxEvtHandler::IsUnlinked)。

ProcessEvent()

virtual bool wxEvtHandler::ProcessEvent 	( 	wxEvent &  	event	) 	

此函数在wxEvtHandler中是公共的,但在wxWindow中受到保护,因为对于wxWindows,您应该始终对GetEventHandler()返回的指针调用ProcessEvent(),而不是对wxWindow对象本身调用。

为方便起见,提供了ProcessWindowEvent()方法作为

GetEventHandler()->ProcessEvent()

请注意,仍然可以直接在wxWindow对象上调用这些函数(例如,将其转换为wxEvtHandler),但当涉及推送事件处理程序的窗口时,这样做会产生微妙的错误。

这也适用于所有其他wxEvtHandler函数。

从wxEvtHandler重新实现。

处理事件,搜索事件表并调用零个或多个合适的事件处理程序函数。

通常,您的应用程序不会调用此函数:它在wxWidgets实现中被调用,以将传入的用户界面事件分派给框架(和应用程序)。

但是,如果在定义新事件类型的地方实现新功能(例如新控件),而不是允许用户重写虚拟函数,则可能需要调用它。

请注意,通常不需要重写ProcessEvent()来定制事件处理,重写专门提供的TryBefore()和TryAfter()函数通常就足够了。例如,wxMDIParentFrame可以重写TryBefore(),以确保菜单事件在父帧本身处理之前在活动子帧中处理。

事件表搜索的正常顺序如下:

1.wxApp::FilterEvent()被调用。如果它返回除-1(默认值)以外的任何值,则处理在此停止。

2.TryBefore()被调用(这是wxWindow对象考虑wxValidator的地方)。如果返回true,则函数退出。

3.如果对象被禁用(通过调用wxEvtHandler::SetEvtHandlerEnabled),则函数跳到步骤(7)。

4.使用Bind<>()绑定的处理程序的动态事件表按照最近绑定到最早绑定的顺序进行搜索。如果找到了一个处理程序,则执行该处理程序,并且函数返回true,除非处理程序使用wxEvent::Skip()表示它没有处理该事件,在这种情况下,搜索将继续。

5.使用事件表宏绑定的处理程序的静态事件表将按照源代码中事件表宏的出现顺序搜索此事件处理程序。如果失败,则尝试基类事件表,依此类推,直到不再存在表或找到合适的函数。如果找到了处理程序,则应用与上一步相同的逻辑。

6.搜索应用于整个事件处理程序链(通常链的长度为1)。此链可以使用wxEvtHandler::SetNextHandler()形成:
在这里插入图片描述

(参考图片,如果调用了A->ProcessEvent,但它不处理该事件,则会调用B->ProcessEvent等等…)。注意,在wxWindow的情况下,您可以构建一个事件处理程序堆栈(有关详细信息,请参阅wxWindow::PushEventHandler())。如果链的任何处理程序返回true,则函数退出。

7.TryAfter()被调用:对于wxWindow对象,这可能会将事件传播到窗口父级(递归)。如果事件仍然未处理,则wxTheApp对象上的ProcessEvent()将作为最后一步调用。

注意,步骤(2)-(6)是在这个函数调用的ProcessEventLocally()中执行的。

参数

event要处理的事件。

退换商品

如果找到并执行了合适的事件处理程序函数,并且该函数未调用wxEvent::Skip,则为true。

wxCommandEvent与新的事件类型一起使用

如果您只想将wxCommandEvent与新的事件类型一起使用,请使用下面列出的通用事件表宏之一,而不必自己定义新的事件类。

// this is typically in a header: it just declares MY_EVENT event type
wxDECLARE_EVENT(MY_EVENT, wxCommandEvent);
 
// this is a definition so can't be in a header
wxDEFINE_EVENT(MY_EVENT, wxCommandEvent);
 
// example of code handling the event with event tables
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_MENU    (wxID_EXIT, MyFrame::OnExit)
    ...
    EVT_COMMAND (ID_MY_WINDOW, MY_EVENT, MyFrame::OnMyEvent)
wxEND_EVENT_TABLE()
 
void MyFrame::OnMyEvent(wxCommandEvent& event)
{
    // do something
    wxString text = event.GetString();
}
 
// example of code handling the event with Bind<>():
MyFrame::MyFrame()
{
    Bind(MY_EVENT, &MyFrame::OnMyEvent, this, ID_MY_WINDOW);
}
 
// example of code generating the event
void MyWindow::SendEvent()
{
    wxCommandEvent event(MY_EVENT, GetId());
    event.SetEventObject(this);
 
    // Give it some contents
    event.SetString("Hello");
 
    // Do send it
    ProcessWindowEvent(event);
}

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

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

相关文章

逆向-还原代码之eth (Interl 64)

// 源程序 #include <stdio.h> #define HIETH_SYSREG_BASE (0x101e0000) #define REG_RESET 0x01C // 外设控制寄存器(IP软复位控制) #define RESET_SHIFT 12 static void hieth_set_regbit(unsigned long addr, int bit, int shift) { unsigned long …

nginx学习笔记1(小d课堂)

我们进入到官网可以看到有很多个版本的nginx。 我们点击documentation&#xff0c;可以看到官方文档&#xff0c;但是这里的文档暂时还没有中文的&#xff1a; 我们这里后期会在linux上进行安装部署nginx。 而我们的nginx就是我们的反向代理服务器。 我们可以这样来配置。 我们…

栈和队列(内附模拟实现代码)

一&#xff0c;栈1.1 栈的概念栈是一种线性表&#xff08;是一种特殊的线性表&#xff09;&#xff0c;栈只允许在固定一端进行插入和删除元素。插入元素的一端称为栈顶&#xff0c;另一端称为栈底。所以栈中的数据元素满足先进后出&#xff08;First In Last Out&#xff09;的…

【数据篇】31 # 如何对海量数据进行优化性能?

说明 【跟月影学可视化】学习笔记。 渲染动态的地理位置 用随机的小圆点模拟地图的小圆点&#xff0c;实现呼吸灯效果 最简单的做法&#xff1a;先创建圆的几何顶点数据&#xff0c;然后对每个圆设置不同的参数来分别一个一个圆绘制上去。 <!DOCTYPE html> <html …

如何使用python删除一个文件?别说,还挺好用....

嗨害大家好鸭&#xff01;我是小熊猫~ 若想利用python删除windows里的文件&#xff0c;这里需要使用os模块&#xff01;那接下来就看看利用os模块是如何删除文件的&#xff01; 具体实现方法如下&#xff01; 更多学习资料:点击此处跳转文末名片获取 os.remove(path) 删除文…

Java位运算符:Java移位运算符、复合位赋值运算符及位逻辑运算符

Java 定义的位运算&#xff08;bitwise operators&#xff09;直接对整数类型的位进行操作&#xff0c;这些整数类型包括 long&#xff0c;int&#xff0c;short&#xff0c;char 和 byte。位运算符主要用来对操作数二进制的位进行运算。按位运算表示按每个二进制位&#xff08…

GitLab安装使用(SSH+Docker两种方式)

GitLab安装使用1、在ssh下安装gitlab1.1 安装依赖1.2 配置镜像1.3 开始安装1.4 gitlab常用命令2、在docker下安装gitlab2.1 安装docker2.1.1 更新yum源2.1.2 安装依赖2.1.3 添加镜像2.1.4 查看源中可用版本2.1.5 安装指定版本2.1.6 配置开机启动项2.2 使用容器安装gitlab2.2.1 …

车载以太网 - DoIP头部信息检测逻辑 - 03

通过前面的文章我们已经了解了DoIP所具备的Payload类型,基础的信息都已经具备了,今天我们就要进一步的去了解DoIP的处理逻辑了;按照正常的逻辑来看,处理无论是我们人眼去看书,还是计算机处理一段数据,都是从前到后依次进行处理;而DoIP的信息处理也不例外,也是从头开始进…

2023跨境出海指南:印度网红营销白皮书

前不久&#xff0c;联合国预测印度人口将在4个月后超过中国&#xff0c;成为全球第一人口大国。印度这个国家虽然有些奇葩&#xff0c;但他们的经济实力确实不能小觑&#xff0c;这也是众多国际公司大力发展印度的原因。出海印度容易&#xff0c;但攻克印度市场太难&#xff0c…

Python Tutorial——类

与其它编程语言相比&#xff0c;Python的类机制添加了最小的新语法和语义。它是C和Modula-3中的类机制的混合。Python的类提供了面向对象编程的所有的标准特性&#xff0c;类继承机制允许有多个基类&#xff0c;一个子类可以重写基类中的任何方法&#xff0c;一个方法可以调用基…

编程思想图书推荐,新手入门应该看些啥

编程思想图书推荐&#xff0c;新手入门应该看些啥 导入 元旦的时候&#xff0c;学校社团的指导老师&#xff0c;咨询我有没有什么可以推荐的编程思想的学习书籍&#xff0c;可以值得推荐精读。 说实话&#xff0c;我个人是买过很多书的&#xff0c;但是很少读书&#xff0c;如果…

搭建redis主从复制+哨兵高可用

从服务器连接主服务器&#xff0c;发送SYNC命令&#xff1b;主服务器接收到SYNC命名后&#xff0c;开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令&#xff1b;主服务器BGSAVE执行完后&#xff0c;向所有从服务器发送快照文件&#xff0c;并在发送期间继续…

Window下安装oracle12C

1.Window下安装oracle12C 官网下载地址&#xff1a; Database Software Downloads | Oracle 页面顶部选择 “接受许可协议” 后&#xff0c;我想选择下载 12c 版的企业版&#xff0c;文件1和文件2都需要下载。&#xff08;如果提示登录 Oracle&#xff0c;则需要先登录才能下…

java家装网装修网站装修系统源码

简介 本平台主要是家装网站。管理员发布装修案例&#xff0c;看工地&#xff0c;装修设计师&#xff0c;装修攻略&#xff0c;装修知识文章等&#xff0c;嵌入3d全景图。普通用户注册&#xff0c;填写装修房型报价等。 演示视频&#xff1a; https://www.bilibili.com/video/…

Kotlin基础入门 - 静态变量、常量 And 静态函数、方法

2022一晃而过&#xff0c;2023悄然而至&#xff0c;有天晚上看第一行代码&#xff08;第三版&#xff09;的时候&#xff0c;又看到了Kotlin中静态方法的几种使用方式&#xff0c;蹭着过年还有一些时间&#xff0c;写了个Demo简单测试记录一下 在 Kotlin 中使用静态的方式不止一…

JavaScript基础系列之原型链

1. 前言 今天的重点复习的是JavaScript原型链。所谓是"基础不牢&#xff0c;地动山摇"&#xff0c;原型链作为继承等相关知识的基础&#xff0c;就显得尤为重要了。接下来以手绘原型链为基础&#xff0c;详解讲解下原型链以及相关的属性 2. 原型 以及原型链 2.1 pro…

vs 生成前事件 生成后事件命令

为了提高编译生成后的事件效率&#xff0c;不需要手动的拷贝到固定目录。可以在项目->属性中设备生成后事件。输入相应的命令行&#xff0c;即可。 Visual Studio中&#xff0c;可以在项目-》属性-》生成事件-》生成后事件命令行 xcopy 复制文件&#xff1b; /y/e 如果只复…

JavaEE【Spring】:MyBatis查询数据库

文章目录一、理论储备1、MyBatis 的概念2、MyBatis 的作用二、第⼀个MyBatis查询1、创建数据库和表2、添加MyBatis框架支持① 老项目添加MyBatisⅠ. 新增功能Ⅱ. EditStarters插件② 新项目添加MyBatis3、配置连接字符串和MyBatis① 配置连接字符串② 配置 MyBatis 中的 XML 路…

数据标注平台如何保护用户数据安全?

近期&#xff0c;在《麻省理工科技评论》在一篇万字长文调查中&#xff0c;一位年轻女子坐在自家的马桶上的图片也被扫地机器人拍摄下来&#xff0c;并被流传到网上、大范围传播。但事实上&#xff0c;这也并非是一件新鲜事了。例如&#xff0c;2020年秋&#xff0c;一系列从低…

为什么MySQL 要选择 B+树

一、什么是索引 在关系数据库中&#xff0c;索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构。再直白点就是我们可以把索引理解成图书或者字典的目录。 既然索引是数据的一种存储结构&#xff0c;那么我们必然要对其进行存储&#xff0c;同时&…