gpt4 book ai didi

c++ - wxWidgets:解除事件触发

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

我正在编写一个 wxWidgets GUI,它涉及通过按钮在 gridsizer 中动态添加和删除控件行。

每一行控件都有一个“删除”按钮,该按钮触发一个事件:

  • 从它们的 sizer 中删除控件
  • 隐藏控件
  • 解除绑定(bind)删除按钮事件
  • 将控件标记为在可重用控件池中可用(我是重新使用控件,因为 wxWidgets 不喜欢在运行时)

现在我不认为在事件处理程序本身中取消绑定(bind)事件是一件好事。有没有更好的方法来实现这种行为?

这就是我动态创建控件的方式

bool filtermanager::add()
{
if (!grid || !box || !form || !bsizer)
return false;

dbgcode(log->d(tag, "add: adding a new filter row"));

// add and index filter in the filter map and refresh layout
filter *flt = new filter(this, box, grid);
filters[flt->removebutton()->GetId()] = flt;
refreshlayout();

return true;
}

filtermanager::filter::filter(filtermanager *parent,
wxStaticBox *box, wxGridSizer *grid)
: parent(parent), grid(grid)
{
controlpool *ctl = parent->ctl;

// initialize filter row elements
property = ctl->makeComboBox(box, "property");
value = ctl->makeTextCtrl(box, "value");
button = ctl->makeButton(box, "Remove");

// add filter row to the grid sizer
grid->SetRows(grid->GetRows() + 1);
grid->Add(property, 0, wxALL | wxEXPAND, 0);
grid->Add(value, 0, wxALL | wxEXPAND, 0);
grid->Add(button, 0, wxALL | wxEXPAND, 0);

// bind remove button
button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &filtermanager::OnRemoveClicked, parent);
}

这是事件处理程序:

void filtermanager::OnRemoveClicked(wxCommandEvent &e)
{
wxButton *b = dynamic_cast<wxButton *>(e.GetEventObject());
filter *flt = filters[b->GetId()];

dbgcode(log->d(tag,
strfmt() << "OnRemoveClicked: remove button event caught" <<
" property=" << flt->propertycombo() <<
" value=" << flt->valuetext() <<
" button=" << flt->removebutton())
);

removebyflt(flt);
}

void filtermanager::removebyflt(filter *flt)
{
int id = flt->id();

// dealloc filter from the map
delete filters[id];
filters[id] = NULL;
filters.erase(id);
}

filtermanager::filter::~filter()
{
controlpool *ctl = parent->ctl;

// unbind button
button->Unbind(wxEVT_COMMAND_BUTTON_CLICKED, &filtermanager::OnRemoveClicked, parent);

// remove the filter from the gui
if (!grid->Detach(property))
parent->log->e(tag, "~filter: failed to remove property from sizer");

if (!grid->Detach(value))
parent->log->e(tag, "~filter: failed to remove value from sizer");

if (!grid->Detach(button))
parent->log->e(tag, "~filter: failed to remove button from sizer");

grid->SetRows(grid->GetRows() - 1);

// refresh panels as usual
parent->refreshlayout();

ctl->free(property);
ctl->free(value);
ctl->free(button);
}

顺便说一句,此 GUI 的目的是为加载的 XML 文件中的属性添加搜索过滤器。

最佳答案

解除事件与其处理程序的绑定(bind)很好,我真的没有看到任何问题,甚至可能这样做。

此外,wxWidgets 在运行时删除控件没有任何特殊问题,一般来说,使用隐藏控件池似乎比仅根据需要删除和重新创建它们更麻烦。但是,从该控件生成的事件的处理程序中删除控件确​​实是一个坏主意,可能会导致崩溃。对此的规范解决方案是立即隐藏控件并“稍后”将其删除,即在下一次事件循环迭代期间。这可以通过在所有版本的 wxWidgets 中显式使用 wxEVT_IDLE 来完成,或者更方便地使用 CallAfter() 来完成。在 wxWidgets 2.9.5 或更高版本中。

关于c++ - wxWidgets:解除事件触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18955287/

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