gpt4 book ai didi

c++ - WxWidget ID 问题

转载 作者:太空宇宙 更新时间:2023-11-04 11:54:24 24 4
gpt4 key购买 nike

简而言之:如何确保事件和/或小部件的“静态”声明 ID 不会在中型到大型项目中发生冲突?

...还有长篇:

在 WxWidgets 中处理 ID 的一种方法是通过每个编译单元的枚举来声明它们,即在小部件的源文件中。但是,当 ID 用于 WxWidgets 的事件处理时,它们应该或必须是全局唯一的。有些不需要是全局唯一的,但我认为如果它们都是唯一的则更安全,否则可能会出现运行时“冲突”,不会触发任何警告 - 事件只是由另一个小部件处理。不幸的是,我遇到过这个问题几次(继承的代码库)——它们很难追踪而且很烦人,除非我遗漏了什么。不管怎样,我想一劳永逸地解决这个问题:-)

我知道,WxWidgets 也支持动态绑定(bind),我们/我在某些地方使用它。但是,更改所有“静态”声明的 ID 的代码将花费太多精力。所以基本上我拥有的是许多单独的源文件(> 60),其中有从 wxID_HIGHEST 开始的枚举,带有一些(看似)任意偏移量。我确实认为偏移量是任意的,很可能是为了解决上述 ID 冲突问题的个别情况而添加的。无论如何,将所有枚举放入单个文件/枚举中似乎有点难看,因为这将是一个非常长的列表。

所以这就是我一直在想的:我使用单个枚举在单个头文件中维护不同小部件的 MIN/MAX-ID,并提供两个开始和结束给定 ID 枚举的宏。 END 宏还应检查声明的 MAX-ID 是否未超出。这听起来明智吗?解决 ID 冲突问题的常用方法有哪些?

我的预期解决方案如下所示。我计划添加一个处理动态绑定(bind) ID 的函数。我知道 WxWidgets 提供了与 ID-reference-counting 相关的功能,但是,我在使用它的时候想...它旨在尽可能与平台无关。

#include <wx/defs.h>
#define NUM_OF_DYNAMIC_AUTO_IDS 500

namespace WxWidgetIdHelper {

enum WxWidgetIDsEnum {
MIN_DYNAMIC_AUTO_ID = wxID_HIGHEST + 1,
MAX_DYNAMIC_AUTO_ID = MIN_DYNAMIC_AUTO_ID + NUM_OF_DYNAMIC_AUTO_IDS,
STATIC_ID_OFFSET = MAX_DYNAMIC_AUTO_ID + 1,

Widget1_MIN_ID = STATIC_ID_OFFSET + 1,
Widget1_MAX_ID = Widget1_MIN_ID + 20,

Widget2_MIN_ID = Widget1_MAX_ID + 1,
Widget2_MAX_ID = Widget2_MIN_ID + 20,
...
};

template<bool> struct MaxIdCheck;
template<> struct MaxIdCheck<false> {};
}

#define BEGIN_WXWIDGET_ID_ENUM(CLASSNAME) \
enum CLASSNAME##_##WXWIDGET_IDs { \
CLASSNAME##_##MIN_ID = WxWidgetIdHelper##::##CLASSNAME##_##MIN_ID,

#define END_WXWIDGET_ID_ENUM(CLASSNAME) CLASSNAME##_##MAX_ID }; \
WxWidgetIdHelper::MaxIdCheck< \
( CLASSNAME##_##MAX_ID>WxWidgetIdHelper::CLASSNAME##_##MAX_ID ) > \
INCREASE##_##CLASSNAME##_##MAX_ID_in_WxWidgetIdHelper_h;

最佳答案

没有统一的答案,但我认为您应该牢记以下几点:

  • ID 不需要是全局唯一的,它们只需要在每个顶级窗口内是唯一的。在一个典型的程序中,每个对话框都由其自己的类表示,因此其中的所有 ID 都仅受该类的控制,让您完全不必关心程序的所有其余部分做了什么。
  • 您可以,而且恕我直言,应该避免对所有控件完全使用 ID。唯一不能保存 ID 的地方是菜单项,因为没有与之关联的对象(您不能绑定(bind)到 wxMenuItem)。但是对于所有控件,最好简单地调用 control->Bind(),在这种情况下您根本不需要指定 ID,因为此控件只会获取事件本身。虽然通过调用 Bind() 替换事件表宏非常简单,但您甚至不必为现有事件表执行此操作,因为它们之间没有任何 ID 冲突,据推测 - 所以您需要做的就是对新的事件处理程序使用 Bind()
  • 如果您使用 XRC——恕我直言,没有理由不这样做——那么您所有的 ID 都是在 XRC 文件中指定的字符串,并且保持字符串不同当然比保持整数 ID 不同简单得多,所以这个问题根本不会出现。值得注意的是,在 XRC 中定义您的菜单会处理 ID 非常便于使用的一种情况。

TL;DR 除了菜单项之外,根本不要使用 ID,如果必须使用它们,请在 XRC 中定义它们。

关于c++ - WxWidget ID 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16773511/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com