2012-08-07 8 views
0

幾個小時我一直在努力學習如何使用wxListBox的wxWidgets。我在官方tutorial上建立了我的「應用程序」,但即使我的代碼與原始代碼沒有區別,我仍無法正常工作。wxListBox - 分段故障

我想添加一個新的項目到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。教程示例工作得很好,所以庫bug不是一種可能性。

編輯: 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

你從哪裏得到的段錯誤? – 2012-08-07 17:57:30

+0

@ H2CO3:只要按下* New按鈕*之後輸入文字即可。 – Robin92 2012-08-07 17:58:58

+0

@ Robin92 - 我認爲H2CO3詢問你的調試器報告它的行號。你在預感或者調試者說的話中添加了一條評論? – Flexo 2012-08-07 18:00:28

回答

-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); 
+0

這是一個非常糟糕的想法。您應該將您的控件ID與您的活動標識分開。請查看發行版中提供的示例,並將您的應用程序基於這些示例,直到您瞭解如何使用wxWidgets慣用語的方式進行操作。 – ravenspoint 2012-08-08 13:51:34

+0

不好?這是如何在上述教程中完成的! – Robin92 2012-08-08 17:49:57

+0

並非如此。請看教程。您將看到爲按鈕和其他小部件選擇的ID不使用事件ID。例如ID_RENAME。 – ravenspoint 2012-08-08 17:54:11

0

從您發佈的調試輸出,你的問題不是與使用列表框但使用wxFrame。我猜你已經搞糟了wxApp實例中的wxFrame處理。

我建議你重新開始,從最小的樣本開始,逐步建立你的應用程序。

+0

但不起作用:) – Robin92 2012-08-07 18:13:02

+2

好吧,在線上放置一個斷點並檢查列表指針的值是否合理。 – ravenspoint 2012-08-07 18:17:10

+0

問題是*這是一個最小樣本*。我沒有更多的代碼,但* MyApp *類繼承自* wxApp *。這個班不可能搞砸了,可以嗎?從調試器輸出,我明白'$ 1 =(wxListBox *)0x0'意味着我的**列表**變量指向* NULL *。好的,爲什麼''list-> Append(「first entry」)''在構造函數中有效? – Robin92 2012-08-08 06:45:24