【问题标题】:Can't figure out how to pass arguments to a bind function无法弄清楚如何将参数传递给绑定函数
【发布时间】:2022-07-16 13:38:04
【问题描述】:

多次尝试在滚动事件函数中传递参数后,它不起作用。

我正在制作一个自定义滚动面板,并且需要在用户向下滚动时触发绑定功能,为此我需要传递将在面板内使用的变量。这不是 wxScrolledWindow 的问题,因为我不必绑定任何东西,只需为它创建一个函数并直接调用它。

其中一些参数我不一定需要传递,因为我可以通过使用 event.GetEventObject(); 来获取它们,但其余的比如 m 这是我需要传递的地图。

在我尝试过的下面显示的解决方案中,我想在“滚动面板”内部或附近制作一个隐藏面板,以便我可以使用event.GetEventObject(); 访问它,但我将其保留为最后的努力(如果那会奏效的话)。我真的希望有一个更简单的方法。任何帮助表示赞赏。

尝试 #1

ScrolledWindow->Bind(wxEVT_SCROLLWIN_PAGEDOWN, &MyFrame::ScrolledWindowCreate, this)(m, ScrolledWindow, ScrolledWindowMain, ScrolledWindowSizer, initalWindowWidth));

尝试 #2

// Saw a thread that said parameters should be put outside

ScrolledWindow->Bind(wxEVT_SCROLLWIN_PAGEDOWN, &MyFrame::ScrolledWindowCreate, this)(m, ScrolledWindowContainerSub, ScrolledWindowMain, ScrolledWindowSizer, initalWindowWidth);

尝试 #3

// Tried to pass the arguments as the userData as in the WxWidgets documentation, the WxWidgets forums suggested it, but I looked and apparently, I need to pass in a wxObject? I don't know how a set of arguments is supposed to be turned into a wxObject 

ScrolledWindow->Bind(wxEVT_SCROLLWIN_PAGEDOWN, &MyFrame::ScrolledWindowCreate, this, -1, (m, ScrolledWindowContainerSub, ScrolledWindowMain, ScrolledWindowSizer, initalWindowWidth);

更新:

所以我发现您需要将参数存储为 wxClientData,我相信我已经成功地做到了,但我仍然不知道如何从中提取单个项目。

struct CustomData final : public wxClientData {

    int PanelNum = 20;
    std::list<std::string> TagList{ "Paid", "Needs invoice" };
    std::map<std::string, std::variant<std::string, std::list<std::string>>> m{ {"TIME","8:69"}, {"HEADER","Title"},{"TAGS", TagList},{"CONTENT", "Hey this is content!"} };
    wxPanel* ScrolledWindowContainerSub;
    wxPanel* ScrolledWindowMain;
    wxBoxSizer* ScrolledWindowSizer;
    int initalWindowWidth = 1300;
};


 // Panels that are set as arguments below are defined here 
// wxPanel* ScrolledWindowContainerSub = ...; etc...

CustomData* const myData{ new CustomData() };
    myData->PanelNum, m, ScrolledWindowContainerSub, ScrolledWindowMain, ScrolledWindowSizer, initalWindowWidth;
    ScrolledWindowContainerSub->SetClientObject(myData);
    ScrolledWindowContainerSub->Bind(wxEVT_SCROLL_BOTTOM, &MyFrame::ScrolledWindowScrolled, this);


void MyFrame::ScrolledWindowScrolled(wxScrollEvent& event) {

wxObject* Obj = event.GetEventObject();
wxClientData* ObjClientData = static_cast<wxEvtHandler*>(Obj)->GetClientObject();


wxPanel* ObjStaticChild = dynamic_cast<wxPanel*>(ObjClientData); // Which panel will this give me? I've put two as parameters

};

【问题讨论】:

  • 第一个版本有2个(和3个),第三个版本有2个(和1个)。你能修复语法错误吗?
  • @mch 我知道语法错误。这些是尝试而不是版本
  • 请针对您的后续问题提出单独的问题。这使得已经存在的答案过时了。
  • @Pal,为什么不让这些变量成为滚动面板的成员?
  • @Pal,让他们成为 MyFrame 类的成员...

标签: c++ wxwidgets


【解决方案1】:

Bind() 确实支持将指针传递给任意“用户数据”,但这不是最好的方法,仅支持向后兼容并简化Bind() 之前的旧代码的迁移。

相反,请考虑将您需要的数据作为某个对象的一部分(通常是从窗口类派生并表示您要绑定的窗口,但不一定如此)并绑定到该对象的成员函数,您可以在其中访问所需的所有数据。

请记住,您不需要绑定到生成事件的对象或其父对象。你可以使用任何你想要的东西,包括一个 lambda,例如。

【讨论】:

  • 把变量放到private下的MyFrame类中,应用崩溃是否正常?我没有收到任何语法错误,滚动事件似乎被拾取,并且 ScrolledWindowScrolled 函数似乎拾取成员变量。不知道怎么办
  • 不,应用程序崩溃绝不是正常的,但这与将成员设为私有无关。检查在绑定到成员时是否将指针传递给正确的对象,即如果您 Bind(..., &amp;Foo::OnSomething, p),您的 p 必须实际指向 Foo 而不是其他东西。
【解决方案2】:

您在Bind 中用于将事件绑定到事件处理程序的语法不正确。

来自event handler's documentation 的正确语法类似于:

//-------------------------------------------------------------------vv--->no need of other things here
Bind(wxEVT_SCROLLWIN_PAGEDOWN, &MyFrame::ScrolledWindowCreate, this);

【讨论】:

  • 是的,我知道,但我正在尝试传递额外的参数
  • @Pal 请参阅bind's documentation,他们在其中提到了其参数。我们只允许传递与这些参数相对应的参数。反复试验(就像您在示例中所做的那样)将不起作用。甚至您给定示例中的语法也是无效的。
猜你喜欢
  • 2017-10-24
  • 2017-09-28
  • 1970-01-01
  • 1970-01-01
  • 2017-11-12
  • 1970-01-01
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多