几个小时以来,我一直在努力学习如何使用 wxWidgets 中的 wxListBox 。我已将我的“应用程序”基于官方tutorial,但即使我的代码与原始代码没有什么不同,我也无法使其正常工作。
我想向wxListBox添加一个新项目,但我得到分段错误。这是我的代码:
class CWindow : public wxFrame {
wxBoxSizer *hbox, *vbox;
wxListBox *list;
wxButton *btnAdd, *btnRemove;
public:
CWindow(int w = 640, int h = 480) : wxFrame(NULL, -1, wxT("Test"), wxDefaultPosition, wxSize(w, h)) {
list = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxSize(w-100, h));
btnAdd = new wxButton(this, -1, wxT("Add"));
btnAdd->Connect(wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) &CWindow::OnNew);
btnRemove = new wxButton(this, -1, wxT("Remove"));
vbox = new wxBoxSizer(wxVERTICAL);
vbox->Add(btnAdd, 1, wxALL | wxEXPAND, 0);
vbox->Add(btnRemove, 1, 0, 0);
hbox = new wxBoxSizer(wxHORIZONTAL);
hbox->Add(list, 1, 0, 0);
hbox->Add(vbox, 0, 0, 0);
SetSizer(hbox);
}
void OnNew(wxCommandEvent &event) {
wxString str = wxGetTextFromUser(wxT("New item:"));
if (str.Len() > 0) list->InsertItems(1, &str, 0); //this line is suspected of causing segfault
}
};
任何想法导致我的问题?
PS。教程示例工作正常,因此库错误不可能。
编辑: gdb 调试程序报告此:
0x00007ffff7a8e492 in wxListBoxBase::InsertItems(unsigned int, wxString const*, unsigned int) () from /usr/lib/x86_64-linux-gnu/libwx_gtk2u_core-2.8.so.0
EDIT2:更多 gdb 转储 之前:
Breakpoint 1, CWindow::OnNew (this=0x725cd0, event=...) at listbox.cpp:32
32 if (str.Len() > 0) list->InsertItems(1, &str, 0);
(gdb) print list
warning: can't find linker symbol for virtual table for `CWindow' value
$1 = (wxListBox *) 0x0
(gdb) up
#1 0x00007ffff7586d35 in wxEvtHandler::ProcessEventIfMatches(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&) ()
from /usr/lib/x86_64-linux-gnu/libwx_baseu-2.8.so.0
答案 0 :(得分:0)
从您发布的调试输出中,问题不在于使用列表框,而在于使用wxFrame。我猜你已经搞砸了wxApp实例中wxFrame的处理。
我建议你重新开始,从最小的样本开始,逐步构建你的应用程序。
答案 1 :(得分:-2)
感谢许多建议,我能够成功解决问题。这是由于将按钮直接连接到功能而引起的。似乎每个按钮必须具有相应的标识符。
所以这是错误的:
button = new wxButton(this, wxID_ANY, wxT("label"));
(...)
button->Connect(wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) &CWindow::OnClick);
这很好:
button = new wxButton(this, EVT_OnClick, wxT("label"));
(...)
Connect(EVT_OnClick, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) &CWindow::OnClick);