0

wxWidgetsのhello world チュートリアルが奇妙な動作を示します。次の行を MyFrame コンストラクターに使用して、アプリケーションにパネルを追加するとすぐに:

wxPanel *panel = new wxPanel(this);

[Return] キーと [Keypad Enter] キーを押すと、プログラムが終了します (Clean Close イベントが検出されます)。

どうしてこれなの?wxPanel がなければ、キーは何もしません。

追加された行を含むコードは次のとおりです。

// hworld.cpp
// Version using dynamic event routing

#include <wx/wx.h>

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

IMPLEMENT_APP(MyApp)


class MyFrame : public wxFrame
{
public:
    MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
    void OnQuit(wxCommandEvent& event);
    void OnAbout(wxCommandEvent& event);
};

enum
{
    ID_Quit=1,
    ID_About
};


bool MyApp::OnInit()
{
    MyFrame *frame = new MyFrame( _("Hello World"), wxPoint(50, 50),
                                wxSize(450, 350));

    frame->Connect( ID_Quit, wxEVT_COMMAND_MENU_SELECTED,
                    (wxObjectEventFunction) &MyFrame::OnQuit );
    frame->Connect( ID_About, wxEVT_COMMAND_MENU_SELECTED,
                    (wxObjectEventFunction) &MyFrame::OnAbout );

    frame->Show(true);
    SetTopWindow(frame);
    return true;
}

MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
    : wxFrame( NULL, -1, title, pos, size )
{
    wxMenuBar *menuBar = new wxMenuBar;

    wxMenu *menuFile = new wxMenu;

    menuFile->Append( ID_About, _("&About...") );
    menuFile->AppendSeparator();
    menuFile->Append( ID_Quit, _("E&xit") );

    menuBar->Append(menuFile, _("&File") );

    // Added line causing failure.
    wxPanel *panel = new wxPanel(this);

    SetMenuBar(menuBar);

    CreateStatusBar();

    SetStatusText( _("Welcome to wxWidgets!") );
}

void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
    Close(true);
}

void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
    wxMessageBox( _("wxWidgets Hello World example."),
                _("About Hello World"),
                wxOK|wxICON_INFORMATION, this );
}           
4

2 に答える 2

0

現在は動作していますが、その理由については大きな推測です。プログラムがクラッシュすることはありませんでした。デバッグでトレースしたところ、close イベントが呼び出されていました。

[Enter] を押すと閉じます。

wxPanel *panel = new wxPanel(this);

これらすべてと同様に:

wxPanel *panel = new wxPanel(this, wxID_ANY);
wxPanel *panel = new wxPanel(this, wxID_ANY, wxDefaultPosition);
wxPanel *panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);

ただし、これは [Enter] を押しても閉じません。

wxPanel *panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxEXPAND);

これらも閉じません:

wxPanel *panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxEXPAND);
wxPanel *panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxCLIP_CHILDREN);
wxPanel *panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxEXPAND | wxCLIP_CHILDREN);

しかし、これは再び閉じます:

    wxPanel *panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxEXPAND | wxCLIP_CHILDREN | wxTAB_TRAVERSAL);

どうやら wxTAB_TRAVERSAL がスタイルに含まれている場合 (これはコンストラクタ BTW のデフォルトです)、[Enter] キーの押下を wxFrame に伝達し、[X] 閉じるボタンをクリックします。

ヒントに近い唯一のものは、ドキュメント内の不可解で一見無関係なメモです。

 Tab traversal is implemented through an otherwise undocumented intermediate wxControlContainer class from which any class can derive in addition to the normal wxWindow base class. Please see wx/containr.h and wx/panel.h to find out how this is achieved.
if not all characters are being intercepted by your OnKeyDown or OnChar handler, it may be because you are using the wxTAB_TRAVERSAL style, which grabs some keypresses for use by child controls.

これは私の最善の推測です。これが意図的な動作なのかバグなのかはわかりません。

于 2013-10-14T04:28:10.490 に答える