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

news2024/9/20 0:54:04

目录

  • 自定义事件
    • wxPostEvent()
    • wxQueueEvent()
    • PopEventHandler()
    • Bind()
    • GetEventUserData()
    • Connect()
    • Unbind()
    • 定义自己的事件类
  • 事件处理程序与虚拟方法

自定义事件

wxPostEvent()

void wxPostEvent 	( 	wxEvtHandler *  	dest,
		const wxEvent &  	event 
	) 	

在GUI应用程序中,此函数使用wxEvtHandler::AddPendingEvent()将事件发布到指定的dest对象。

否则,它将使用wxEvtHandler::ProcessEvent()立即分派事件。有关详细信息(和注意事项),请参阅相应的文档。由于wxEvtHandler::AddPendingEvent()的限制,此函数对于具有wxString字段的事件对象不是线程安全的,请改用wxQueueEvent()。

#include <wx/event.h> 

wxQueueEvent()

void wxQueueEvent 	( 	wxEvtHandler *  	dest,
		wxEvent *  	event 
	) 	

将事件排入队列,以便对给定对象进行处理。

这是wxEvtHandler::QueueEvent()的包装器,有关详细信息,请参阅其文档。

包含文件:

#include <wx/event.h>

参数

dest要对事件进行排队的对象不能为NULL。

event分配给队列的堆和非NULL事件,函数将拥有它的所有权。

PopEventHandler()


wxEvtHandler* wxWindow::PopEventHandler 	( 	bool  	deleteHandler = false	) 	

删除并返回事件处理程序堆栈上最顶部的事件处理程序。

在以下情况下:

在这里插入图片描述

当调用W->PopEventHandler()时,事件处理程序A将被删除,而B将是堆栈的第一个处理程序。

请注意,当此窗口上没有推送事件处理程序时(即当窗口本身是其唯一的事件处理程序),调用此函数是错误的。

参数

deleteHandler如果这是真的,那么在移除处理程序之后,它将被删除(返回的值将为NULL)。

Bind()

 template<typename EventTag , typename Functor >
void wxEvtHandler::Bind 	( 	const EventTag &  	eventType,
		Functor  	functor,
		int  	id = wxID_ANY,
		int  	lastId = wxID_ANY,
		wxObject *  	userData = NULL 
	) 		

将给定函数、函子或方法与事件动态绑定。

这提供了与Connect()基本相同的功能,但它更灵活,因为它还允许您使用普通函数和任意函子作为事件处理程序。它也比Connect()限制更少,因为可以使用任意方法作为事件处理程序,而Connect()需要wxEvtHandler派生的处理程序。

有关此函数的详细说明,请参阅动态事件处理,有关用法示例,请参阅事件示例示例。

参数

eventType要与此事件处理程序关联的事件类型。

functor事件处理程序函子。这可以是一个普通函数,也可以是任意函子,如boost::function<>。

id要与事件处理程序关联的标识符范围的第一个id。

lastId要与事件处理程序关联的标识符范围的最后一个ID。

userData与事件表条目关联的可选数据。wxWidgets将拥有该指针的所有权,即当事件处理程序断开连接或程序终止时,该指针将被销毁。稍后可以使用wxEvent::GetEventUserData()检索此指针。

GetEventUserData()

wxObject* wxEvent::GetEventUserData 	( 		) 	const

返回与动态连接的事件处理程序关联的用户数据。

wxEvtHandler::Connect()和wxEvt handler::Bind()允许将可选的userData指针与处理程序关联,此方法返回此指针的值。

返回的指针由wxWidgets拥有,不能删除。

Connect()

void wxEvtHandler::Connect 	( 	int  	id,
		int  	lastId,
		wxEventType  	eventType,
		wxObjectEventFunction  	function,
		wxObject *  	userData = NULL,
		wxEvtHandler *  	eventSink = NULL 
	) 	

将给定函数、函子或方法与事件动态绑定。

这提供了与Connect()基本相同的功能,但它更灵活,因为它还允许您使用普通函数和任意函子作为事件处理程序。它也比Connect()限制更少,因为可以使用任意方法作为事件处理程序,而Connect()需要wxEvtHandler派生的处理程序。

有关此函数的详细说明,请参阅动态事件处理,有关用法示例,请参阅事件示例示例。

参数

eventType要与此事件处理程序关联的事件类型。

functor事件处理程序函子。这可以是一个普通函数,也可以是任意函子,如boost::function<>。

id要与事件处理程序关联的标识符范围的第一个id。

lastId要与事件处理程序关联的标识符范围的最后一个ID。

userData与事件表条目关联的可选数据。wxWidgets将拥有该指针的所有权,即当事件处理程序断开连接或程序终止时,该指针将被销毁。稍后可以使用wxEvent::GetEventUserData()检索此指针。

Unbind()

 template<typename EventTag , typename Functor >
bool wxEvtHandler::Unbind 	( 	const EventTag &  	eventType,
		Functor  	functor,
		int  	id = wxID_ANY,
		int  	lastId = wxID_ANY,
		wxObject *  	userData = NULL 
	) 	

使用指定的参数作为搜索条件,从事件处理程序中动态取消绑定给定的函数、函子或方法,如果找到并删除了匹配的函数,则返回true。

此方法只能解除绑定使用Bind<>()方法添加的函数、函子或方法。无法解除绑定使用(静态)事件表绑定的函数。

目前,函子是通过它们的地址进行比较的,不幸的是,如果相同的地址被重复用于两个不同的函子对象,则无法正常工作。因此,如果有多个函子使用相同的eventType和id以及lastId,则不建议使用Unbind()。

参数

eventType与此事件处理程序关联的事件类型。

functor事件处理程序函子。这可以是一个普通函数,也可以是任意函子,如boost::function<>。

id与事件处理程序关联的标识符范围的第一个id。

lastId与事件处理程序关联的标识符范围的最后一个ID。

userData与事件表条目关联的数据。

定义自己的事件类

在某些情况下,您必须定义自己的事件类,例如,将更复杂的数据从一个地方发送到另一个地方。除了定义事件类之外,如果仍然需要使用事件表(现在被认为是遗留的)来处理此类事件,还需要定义自己的事件表宏。有关新wxEvent派生类的完整工作实现,请参阅事件示例中的ChessBoardEvent。

下面是一个简单的例子:

// create a new event class derived from wxEvent
class MyPlotEvent: public wxEvent
{
public:
    MyPlotEvent(wxEventType eventType, int winid, const wxPoint& pos)
        : wxEvent(winid, eventType),
          m_pos(pos)
    {
    }
 
    // accessors
    wxPoint GetPoint() const { return m_pos; }
 
    // implement the base class pure virtual
    virtual wxEvent *Clone() const { return new MyPlotEvent(*this); }
 
private:
    const wxPoint m_pos;
};
 
// We use a single myEVT_PLOT_CLICKED event type associated with the class
// above but often you are going to have more than one event type, e.g. you
// could also have myEVT_PLOT_ZOOMED or myEVT_PLOT_PANNED etc. -- in which case
// you would just add more similar lines here.
//
// Note that this macro, as all declarations, should be in the header, and
// there should be a matching definition macro in some source file (see
// wxDEFINE_EVENT below).
wxDECLARE_EVENT(myEVT_PLOT_CLICKED, MyPlotEvent);
 
 
// --- Skip this part if you're only going to use Bind() (as recommended) ---
 
// The following typedef and macro are needed only when the new event class
// still needs to be used with the legacy approach to handling events - event
// table macros or Connect() - to cast the type of a function handling it to
// the type expected by the legacy event handling machinery.
typedef void (wxEvtHandler::*MyPlotEventFunction)(MyPlotEvent&);
#define MyPlotEventHandler(func) wxEVENT_HANDLER_CAST(MyPlotEventFunction, func)
 
// If the new event is to be used with event tables, a macro for creating
// event table entries for the new event type must be defined.
#define EVT_PLOT_CLICKED(id, func) \
    wx__DECLARE_EVT1(myEVT_PLOT_CLICKED, id, MyPlotEventHandler(func))
 
// --- End of the part which is only relevant when using event tables ---
 
 
// Up until now, we only had declarations that would typically appear in a
// header file. Starting from now we have the definitions, which must occur
// only once in the program and so need to be in a source file.
 
// This defines the event type declared above. If you use multiple event types,
// you need to do it for each of them.
wxDEFINE_EVENT(myEVT_PLOT_CLICKED, MyPlotEvent);
 
// example of code handling the event (you will use one of these methods,
// not both, of course):
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_PLOT_CLICKED(ID_MY_WINDOW, MyFrame::OnPlot)
wxEND_EVENT_TABLE()
 
MyFrame::MyFrame()
{
    Bind(myEVT_PLOT_CLICKED, &MyFrame::OnPlot, this, ID_MY_WINDOW);
}
 
void MyFrame::OnPlot(MyPlotEvent& event)
{
    ... do something with event.GetPoint() ...
}
 
 
// example of code generating the event:
void MyWindow::SendEvent()
{
    MyPlotEvent event(myEVT_PLOT_CLICKED, GetId(), wxPoint(...));
    event.SetEventObject(this);
    ProcessWindowEvent(event);
}

事件处理程序与虚拟方法

可能需要注意的是,wxWidgets的事件处理系统在精神上实现了类似于普通C++中的虚拟方法:这两种机制都允许您通过在派生类中定义事件处理函数来改变基类的行为。

然而,当您想要从派生类处理程序调用基类实现的默认行为时,这两种机制之间有一个重要的区别。对于虚拟函数,您需要直接调用基类函数,您可以在派生类处理程序函数的开头(后处理事件)或结尾(预处理事件)执行该操作。使用事件处理程序,您只能选择预处理事件,为了仍然让默认行为发生,您必须调用wxEvent::Skip(),而不是直接调用基类事件处理程序。事实上,事件处理程序可能甚至不存在于基类中,因为默认行为通常由底层工具包或操作系统本身在特定于平台的代码中实现。但即使它确实存在于wxWidgets级别,也不应该直接调用它,因为事件处理程序不是wxWidget API的一部分,也不应直接调用。

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

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

相关文章

云开发项目中如何管理用户和管理授权?

管理用户 在项目中添加用户后&#xff0c;才能为用户授予对应的资产管理权限。支持修改已创建用户的密码和删除用户。 本文中的 用户 是指在云项目下创建的 B 端子账号&#xff0c;可以和资产授权配合使用&#xff0c;管理 B 端设备和资产。这些 B 端用户账号可以在 智慧行业…

IOS开发基础 · SwiftUI · CS193p Lecture1-2

IOS开发Lecture 1TextRoundedRectangleZstackLecture 2HStackstruct整合组件ContentViewstruct 中创建变量var&letSwiftUI刷新重建点击效果ArrayForeachButtonSpacervar整合小组件SF-symbol上下界限制简化ButtonLecture 1 Text import SwiftUIstruct ContentView: View {…

Node.js 中 cookie的验证登录

认识 cookie 在讲cookie的登录验证之前&#xff0c;先来了解一下cookie是什么&#xff1f;cookie本质是存储在浏览器中的一小段文本信息&#xff08;不超过4kb&#xff09;&#xff0c;是由服务器生成发送到浏览器&#xff08;客户端&#xff09;&#xff0c;浏览器将其保存在…

虚拟化技术学习笔记2

1、虚拟机与容器对比&#xff1a; 2、Hypervisor管理工具对比&#xff1a; 3、QEMU&#xff1a; 软件模拟虚拟化、可以模拟多种硬件&#xff0c;包括X86架构处理器、AMD64架构处理器、ARM、SPARC与PowerPC、AIX架构等&#xff0c;效率低、一般用于研究测试场景。QEMU可以模拟一…

偏微分题目的解法

介绍偏微分是考研数学里的小重点&#xff0c;通常在题干中就能很明显看到偏导数。这种题目一般会有两个小题&#xff0c;且第一题往往送分题&#xff0c;通常是求某个复合函数的偏导&#xff0c;直接用复合函数的求导法则即可得到答案。第二题通常是求原函数&#xff0c;一般来…

NVIDIA 在 WeNet 中开源 Noisy Student Training 方案

为了改进 Noisy Student Training 在非目标领域 ASR 上的性能&#xff0c;英伟达提出新型数据筛选方法 LM Filter。其利用不同解码方式的识别文本之间的差异来作为数据筛选条件&#xff0c;是一个完全无监督的筛选过程。在 AIShell-1 上与无数据筛选的基线相比可以有 10.4% 的性…

PYNQ-Z2 开发板

1. 官方手册写的挺全&#xff0c;了解一下PYNQ-Z2 设置指南 https://pynq.readthedocs.io/en/latest/getting_started/pynq_z2_setup.htmlPYNQ-Z2 Reference Manual v1.0 https://www.mouser.com/datasheet/2/744/pynqz2_user_manual_v1_0-1525725.pdfpynq&#xff08;Python O…

单分散PEG之Amino-PEG24-acid;CAS:196936-04-6氨基-二十四聚乙二醇-羧酸

Amino-PEG24-acid氨基-二十四聚乙二醇-羧酸196936-04-6 中文名称&#xff1a;氨基-二十四聚乙二醇-羧酸 英文名称&#xff1a;Amino-PEG24-acid 分子式&#xff1a;C51H103NO26 分子量&#xff1a;1146.35 CAS&#xff1a;196936-04-6 外观&#xff1a;粘稠液体或者固体粉末&a…

数据的存储(3)浮点数的存储

tips 1. 2. 浮点数内存存储方式与整型是截然不同&#xff0c;不可被整型思维带偏了 我用一个例子来理解浮点数在内存当中的表示方法&#xff0c;先上一个十进制浮点数13.5 1. 利用二进制的权重化为二进制浮点数 二进制权重表小数部分如下&#xff1a; 那么13.5&…

Vue好难理解怎么办?

Vue学习笔记分享给你&#xff0c;希望对你有些帮助&#xff0c;另外推荐2个安装 VScode 中的 Vue 插件 Vue 3 Snippets Vue 3 Snippets - Visual Studio Marketplace 这个插件包含了所有的 Vue.js 2 和 Vue.js 3 的 api 对应的代码片段。插件的代码片段如下表格所示&#xff0…

Jetson nano 入手系列之4—外围设备:开机键+PWM风扇

Jetson nano 入手系列之4—外围设备&#xff1a;开机键PWM风扇1.外接按键开机2.PWM可调速风扇2.1 jtop工具2.2 PWM风扇2.3 PWM风扇的控制2.3.1 手动控制2.3.2 自动控制参考文献本系列针对亚博科技jetson nano开发板。 Jetson nano 入手系列&#xff1a; Jetson nano 入手系列之…

《MySQL系列-InnoDB引擎11》InnoDB关键特性-刷新邻接页

InnoDB 关键特性 InnoDB存储引擎的关键特性包括&#xff1a; Insert Buffer (插入缓冲)Double Write (两次写)Adaptive Hash Index (自适应哈希索引)Async IO (异步IO)Flush Neighbor Page (刷新领接页) 这些特性为InnoDB存储引擎带来了更好的性能以及更高的可靠性。 刷新邻接…

极光笔记 | 当前最佳实践:Header Bidding 与瀑布流混合请求技术

通过这篇文章您讲将了解&#xff1a;Header Bidding 的发展史Waterfall、Header Bidding 的逻辑及优劣势为什么说 Header Bidding 与瀑布流混合请求技术是当前最佳实践PART 01、Header Bidding 的起源Header Bidding&#xff08;头部竞价&#xff0c;又称 Pre-Bidding 或 Advan…

PaddleSports:“AI+体育”端到端开发套件及落地实践

本系列根据WAVE SUMMIT2022深度学习开发者峰会「开源开放 生态共建」论坛嘉宾分享整理。本文整理自「开源开放 生态共建」百度研究院的资深研究员卢飞翔的主题演讲——PaddleSports&#xff1a;“AI体育”端到端开发套件及落地实践。百度3DAI智慧体育团队针对数据、算法、产品三…

C++语法基础课 习题5 —— 字符串

文章目录例题1. 760.字符串的长度(fgets函数)重点&#xff01;2. 761.字符串中数字的个数3. 763.循环相克令4. 765.字符串加空格(getline函数auto用法)重点&#xff01;5. 769.替换字符 重点&#xff01;6. 773.字符串的插入(substr函数)重点!7. 772.只出现一次的字符(难题)习题…

Python逆向进阶教程笔记(1)

视频地址&#xff1a;Day1初识JS逆向 混淆与无混淆数据加密方案解析实战-36Kr数据加密解析 (AES数据逆向)_哔哩哔哩_bilibili 未完待续 一、排错 1.1&#xff09; 目的&#xff1a;抓页面借口&#xff0c;简单请求会被拦截 1.2&#xff09; 网址&#xff1a;乌海市公共资源…

OSPF-MGRE实验(1.3)

要求&#xff1a; 1、首先为每个路由器配置接口ip和环回ip实现第一个目标 r1&#xff1a; [r1]interface GigabitEthernet 0/0/0 [r1-GigabitEthernet0/0/0]ip add 16.1.1.1 24 [r1-GigabitEthernet0/0/0]int gi0/0/1 [r1-GigabitEthernet0/0/1]ip add 61.1.1.1 24 [r1-Gigab…

java File类详细

目录 File创建 1.File&#xff08;String pathname&#xff09; 2. File&#xff08;String parent,String child&#xff09; 3.File(File f,String child) file类的使用 基本操作&#xff1a; 文件夹的操作 File创建 1.File&#xff08;String pathname&#xff09; …

一起快速了解单片机入门知识吧!

从事计算机和电子信息技术行业的都熟知单片机一词&#xff0c;但是你真的了解单片机吗&#xff1f;单片机的种类有哪些&#xff1f;单片机有什么特点&#xff1f;单片机的工作原理是什么&#xff1f;下面一起来了解单片机知识吧&#xff01;在学习单片机知识前&#xff0c;我们…

多数据库学习之SQL Server查询表自增主键字段信息SQL

多数据库学习之SQL Server查询表自增主键字段信息SQL前言概念SQL样例方式一&#xff1a;系统内置存储过程查找方式二&#xff1a;通过INFORMATION_SCHEMA模式下系统视图获取方式三&#xff1a;通过sys模式下系统视图获取参考链接前言 Microsoft SQL Server简介 Microsoft SQL S…