wxWidgets UI应用程序在C ++中为4个或更多wxBoxSizer对象提供分段错误

时间:2014-02-10 04:09:01

标签: c++ user-interface wxwidgets codeblocks

我在C ++ GUI应用程序中添加4个或更多wxBoxSizer(或任何其他类型的Sizer对象)时遇到问题。这是我第一次使用wxWidgets创建GUI应用程序,我使用Code :: Blocks作为IDE。请帮助我如果有人之前有这个问题并解决它。

以下是完整的程序。

主要框架类实现:

/***************************************************************
 * Name:      testWXWProjectMain.h
 * Purpose:   Defines Application Frame
 * Author:    test ()
 * Created:   2014-01-22
 * Copyright: test ()
 * License:
 **************************************************************/

#ifndef TESTWXWPROJECTMAIN_H
#define TESTWXWPROJECTMAIN_H

//(*Headers(testWXWProjectFrame)
#include <wx/sizer.h>
#include <wx/button.h>
#include <wx/menu.h>
#include <wx/panel.h>
#include <wx/statusbr.h>
#include <wx/frame.h>
//*)

class testWXWProjectFrame: public wxFrame
{
    public:

        testWXWProjectFrame(wxWindow* parent,wxWindowID id = -1);
        virtual ~testWXWProjectFrame();

    private:

        //(*Handlers(testWXWProjectFrame)
        void OnQuit(wxCommandEvent& event);
        void OnAbout(wxCommandEvent& event);
        //*)

        //(*Identifiers(testWXWProjectFrame)
        static const long ID_BUTTON1;
        static const long ID_BUTTON2;
        static const long ID_PANEL2;
        static const long ID_PANEL1;
        static const long ID_MENUITEM1;
        static const long idMenuAbout;
        static const long ID_STATUSBAR1;
        //*)

        //(*Declarations(testWXWProjectFrame)
        wxPanel* Panel1;
        wxStatusBar* StatusBar1;
        wxButton* Button1;
        wxButton* Button2;
        wxPanel* Panel2;
        //*)

        DECLARE_EVENT_TABLE()
};

#endif // TESTWXWPROJECTMAIN_H


####################################################
/***************************************************************
 * Name:      testWXWProjectMain.cpp
 * Purpose:   Code for Application Frame
 * Author:    test ()
 * Created:   2014-01-22
 * Copyright: test ()
 * License:
 **************************************************************/

#include "testWXWProjectMain.h"
#include <wx/msgdlg.h>

//(*InternalHeaders(testWXWProjectFrame)
#include <wx/string.h>
#include <wx/intl.h>
//*)

//helper functions
enum wxbuildinfoformat {
    short_f, long_f };

wxString wxbuildinfo(wxbuildinfoformat format)
{
    wxString wxbuild(wxVERSION_STRING);

    if (format == long_f )
    {
#if defined(__WXMSW__)
        wxbuild << _T("-Windows");
#elif defined(__UNIX__)
        wxbuild << _T("-Linux");
#endif

#if wxUSE_UNICODE
        wxbuild << _T("-Unicode build");
#else
        wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
    }

    return wxbuild;
}

//(*IdInit(testWXWProjectFrame)
const long testWXWProjectFrame::ID_BUTTON1 = wxNewId();
const long testWXWProjectFrame::ID_BUTTON2 = wxNewId();
const long testWXWProjectFrame::ID_PANEL2 = wxNewId();
const long testWXWProjectFrame::ID_PANEL1 = wxNewId();
const long testWXWProjectFrame::ID_MENUITEM1 = wxNewId();
const long testWXWProjectFrame::idMenuAbout = wxNewId();
const long testWXWProjectFrame::ID_STATUSBAR1 = wxNewId();
//*)

BEGIN_EVENT_TABLE(testWXWProjectFrame,wxFrame)
    //(*EventTable(testWXWProjectFrame)
    //*)
END_EVENT_TABLE()

testWXWProjectFrame::testWXWProjectFrame(wxWindow* parent,wxWindowID id)
{
    //(*Initialize(testWXWProjectFrame)
    wxMenuItem* MenuItem2;
    wxMenuItem* MenuItem1;
    wxBoxSizer* BoxSizer3;
    wxMenu* Menu1;
    wxBoxSizer* BoxSizer2;
    wxBoxSizer* BoxSizer4;
    wxBoxSizer* BoxSizer1;
    wxMenuBar* MenuBar1;
    wxMenu* Menu2;

    Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("wxID_ANY"));
    BoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
    BoxSizer2 = new wxBoxSizer(wxHORIZONTAL);
    Panel2 = new wxPanel(this, ID_PANEL2, wxDefaultPosition, wxSize(236,171), wxTAB_TRAVERSAL, _T("ID_PANEL2"));
    BoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
    Button1 = new wxButton(Panel2, ID_BUTTON1, _("button 1"), wxDefaultPosition, wxSize(121,27), 0, wxDefaultValidator, _T("ID_BUTTON1"));
    BoxSizer4->Add(Button1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    Button2 = new wxButton(Panel2, ID_BUTTON2, _("button2"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON2"));
    BoxSizer4->Add(Button2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    Panel2->SetSizer(BoxSizer4);
    SetSizer(BoxSizer4);
    Layout();
    BoxSizer2->Add(Panel2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer1->Add(BoxSizer2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
    Panel1 = new wxPanel(this, ID_PANEL1, wxDefaultPosition, wxSize(262,206), wxTAB_TRAVERSAL, _T("ID_PANEL1"));
    BoxSizer3->Add(Panel1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer1->Add(BoxSizer3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    SetSizer(BoxSizer1);
    MenuBar1 = new wxMenuBar();
    Menu1 = new wxMenu();
    MenuItem1 = new wxMenuItem(Menu1, ID_MENUITEM1, _("Quit\tAlt-F4"), _("Quit the application"), wxITEM_NORMAL);
    Menu1->Append(MenuItem1);
    MenuBar1->Append(Menu1, _("&File"));
    Menu2 = new wxMenu();
    MenuItem2 = new wxMenuItem(Menu2, idMenuAbout, _("About\tF1"), _("Show info about this application"), wxITEM_NORMAL);
    Menu2->Append(MenuItem2);
    MenuBar1->Append(Menu2, _("Help"));
    SetMenuBar(MenuBar1);
    StatusBar1 = new wxStatusBar(this, ID_STATUSBAR1, 0, _T("ID_STATUSBAR1"));
    int __wxStatusBarWidths_1[1] = { -1 };
    int __wxStatusBarStyles_1[1] = { wxSB_NORMAL };
    StatusBar1->SetFieldsCount(1,__wxStatusBarWidths_1);
    StatusBar1->SetStatusStyles(1,__wxStatusBarStyles_1);
    SetStatusBar(StatusBar1);
    BoxSizer1->Fit(this);
    BoxSizer1->SetSizeHints(this);

    Connect(ID_MENUITEM1,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&testWXWProjectFrame::OnQuit);
    Connect(idMenuAbout,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&testWXWProjectFrame::OnAbout);
    //*)
}

testWXWProjectFrame::~testWXWProjectFrame()
{
    //(*Destroy(testWXWProjectFrame)
    //*)
}

void testWXWProjectFrame::OnQuit(wxCommandEvent& event)
{
    Close();
}

void testWXWProjectFrame::OnAbout(wxCommandEvent& event)
{
    wxString msg = wxbuildinfo(long_f);
    wxMessageBox(msg, _("Welcome to..."));
}

申请类:

/***************************************************************
 * Name:      testWXWProjectApp.h
 * Purpose:   Defines Application Class
 * Author:    test ()
 * Created:   2014-01-22
 * Copyright: test ()
 * License:
 **************************************************************/

#ifndef TESTWXWPROJECTAPP_H
#define TESTWXWPROJECTAPP_H

#include <wx/app.h>

class testWXWProjectApp : public wxApp
{
    public:
        virtual bool OnInit();
};

#endif // TESTWXWPROJECTAPP_H

    /***************************************************************
 * Name:      testWXWProjectApp.cpp
 * Purpose:   Code for Application Class
 * Author:    test ()
 * Created:   2014-01-22
 * Copyright: test ()
 * License:
 **************************************************************/

#include "testWXWProjectApp.h"

//(*AppHeaders
#include "testWXWProjectMain.h"
#include <wx/image.h>
//*)

IMPLEMENT_APP(testWXWProjectApp);

bool testWXWProjectApp::OnInit()
{
    //(*AppInitialize
    bool wxsOK = true;
    wxInitAllImageHandlers();
    if ( wxsOK )
    {
        testWXWProjectFrame* Frame = new testWXWProjectFrame(0);
        Frame->Show();
        SetTopWindow(Frame);
    }
    //*)
    return wxsOK;

}

调试:

Adding source dir: /home/nisshanka/projects/codes/testWXWProject/
Adding source dir: /home/nisshanka/projects/codes/testWXWProject/
Adding file: /home/nisshanka/projects/codes/testWXWProject/bin/Debug/testWXWProject
Changing directory to: /home/nisshanka/projects/codes/testWXWProject/.
Set variable: LD_LIBRARY_PATH=.:/usr/local/lib:/usr/lib64:
Starting debugger: /usr/bin/gdb -nx -fullname  -quiet  -args /home/nisshanka/projects/codes/testWXWProject/bin/Debug/testWXWProject
done
Registered new type: wxString
Registered new type: STL String
Registered new type: STL Vector
Setting breakpoints
Debugger name and version: GNU gdb (GDB) Red Hat Enterprise Linux (7.2-56.el6)
At /home/nisshanka/projects/codes/testWXWProject/testWXWProjectApp.cpp:26
At /home/nisshanka/projects/codes/testWXWProject/testWXWProjectApp.cpp:27
Continuing...
Program received signal SIGSEGV, Segmentation fault.
In wxSizer::GetMinSize() () (/usr/local/lib/libwx_gtk2_core-2.8.so.0)
#20 0x0000000000409d06 in testWXWProjectApp::OnInit (this=0x630840) at /home/nisshanka/projects/codes/testWXWProject/testWXWProjectApp.cpp:27
/home/nisshanka/projects/codes/testWXWProject/testWXWProjectApp.cpp:27:626:beg:0x409d06
At /home/nisshanka/projects/codes/testWXWProject/testWXWProjectApp.cpp:27
#20 0x0000000000409d06 in testWXWProjectApp::OnInit (this=0x630840) at /home/nisshanka/projects/codes/testWXWProject/testWXWProjectApp.cpp:27
/home/nisshanka/projects/codes/testWXWProject/testWXWProjectApp.cpp:27:626:beg:0x409d06
Continuing...
Program terminated with signal SIGSEGV, Segmentation fault.
Debugger finished with status 0

我也试过了不同的sizer,但总是给出了分段错误。如果我使用3个sizer,那么它没有任何问题。 感谢。

1 个答案:

答案 0 :(得分:2)

您无法将sizer设置为多个wxWindows。例如,在testWXWProjectFrame::testWXWProjectFrame中,您有

Panel2->SetSizer(BoxSizer4);
SetSizer(BoxSizer4);

这将为Panel2设置相同的sizer,Panel2创建为框架的子项,并设置为框架本身。通常,您需要为每个容器(wxPanelwxFrame)创建一个box sizer,并使用wxWindow::SetSizer将该sizer与容器相关联。另外,如果为特定容器创建了sizer,例如, Panel2,然后只有Panel2的子项可以添加到该sizer(或者只包含Panel2子项的sizer。

在你的代码中,这些关系都是混乱的。另外,为什么首先将BoxSizer4设置为框架的sizer,然后在方法结束时将其替换为BoxSizer1

我还建议您为变量使用有意义的名称。如果源代码包含BoxSizer1Panel2等名称,则很难阅读它。另外,我有时发现将control / sizer层次结构写成这样的树是有帮助的:

  • 框架(BoxSizer4)
    • Panel2(BoxSizer4)
      • Button1的
      • 将Button2
    • Panel1(BoxSizer3)

这样可以更容易地检查是否将正确的控件添加到正确的sizer中,并将sizer设置为正确的容器。在这里,您可以快速发现BoxSizer4被设置为两个控件,其中一个是另一个控件的子项 - 这将导致崩溃,例如您正在看到的那个。