Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [wx] Не перехватывается событие WXK_TAB


Автор: JavaCraft 13.11.2008, 21:20
Обработчик событий клавиатуры не перехватывает код WXK_TAB.
Если подставить другие коды (например WXK_ESCAPE, WXK_DELETE и т.д.), то функция вызывается и правильно работает.
Фокус на объект выставляется, все другие обработчики работают, что еще ему нужно не знаю.

 В чем может быть проблема?

Код

void wxMyScrolledWindow::OnKeyDown(wxKeyEvent & event){
    long keycode = event.GetKeyCode();
    switch(keycode){
/// ...
        case WXK_TAB: m_pObject->m_ElementTab(); break;
/// ...
        default:{m_pObject->m_DefaultMethod(); break;}
    }
    DoDraw(m_DC);
    Refresh();
}



Так и не работает. Это фича wx, я почти уверен.

Автор: t_rex 19.11.2008, 18:32
http://www.lpthe.jussieu.fr/~zeitlin/wxWindows/docs/wxwin_wxnavigationkeyevent.html
может это? + поковырять флаг wxTAB_TRAVERSAL

Автор: JavaCraft 19.11.2008, 21:40
По ссылке немного недопонял, что делать?
Флаг ковырял, создавал объект и с флагом и без него, и в дизайнере панели(в которые объект вставляется) и так и сяк конфигурировал.

Автор: t_rex 21.11.2008, 01:38
Сделать обработчик события EVT_NAVIGATION_KEY(), в нем проверять IsFromTab() и делать что надо.
--
А вобще лучше, наверное, опиши чего ты хочешь добиться обработкой таба? Может какое-то более стандартное решение можно придумать?

Автор: JavaCraft 21.11.2008, 15:19
Цитата(t_rex @ 21.11.2008,  01:38)
Сделать обработчик события EVT_NAVIGATION_KEY(), в нем проверять IsFromTab() и делать что надо.
--
А вобще лучше, наверное, опиши чего ты хочешь добиться обработкой таба? Может какое-то более стандартное решение можно придумать?

У меня обработчик OnKeyDown обрабатывает все события клавиатуры, отдельно от других событий.
Существует много примеров wxWidgets, где TAB используется именно так, как я показал.
Почему в данном случае не работает, не понятно. Ну хотя бы один раз должен сработать, даже если фокус меняется.

Вы предлагаете для TAB сделать отдельный обработчик EVT_NAVIGATION_KEY().
Т.е. разделить обработку событий клавиатуры на навигационные и не навигационные?

Задача стандартная, что ни на есть, для TAB. 1) Перебор узлов в цепочке в векторном объекте наложенном на изображение, в случае если начальный(текущий) узел задан. Новый текущий узел, становится активным в некотором смысле. 2) Перебор целых векторных объектов на изображении если начальный узел или объект не заданы. Выбранный объект становится активным, текущий узел остается не заданным.

Алгоритм прекрасно работает с любой другой клавишей, но TAB более правильно использовать, как логически так интуитивно, т.е. аналогично перебору контролов на форме, чтобы пользователю не нужно было запоминать разные клавиши для одинаковой задачи.

Автор: t_rex 21.11.2008, 16:58
Щаз вот посмотрел. Похоже что для реализации этого функционала надо чтобы все контейнеры, в которых находится ваш компонент не имели флага wxTAB_TRAVERSAL. Т.е. если надо обрабатывать TAB и ваш контрол находится где-то там во вложенных панелях, то все выше стоящие панели также не должны иметь флаг wxTAB_TRAVERSAL. Но ИМХО это не очень хороший подход. Программулина тогда accessibility-тест не пройдет. Т.е., допустим, поставили фокус на контрол а потом клавиатурой никуда из него выйти не сможем.
У меня вот такое нормально работает
Код

/////////////////////////////////////////////////////////////////////////////
// Name:        wxMyScrolledWindow.cpp
// Purpose:     
// Author:      Volodymir (T-Rex) Tryapichko
// Modified by: 
// Created:     21/11/2008 15:34:26
// RCS-ID:      
// Copyright:   Volodymir (T-Rex) Tryapichko, 2008
// Licence:     
/////////////////////////////////////////////////////////////////////////////

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

////@begin includes
////@end includes

#include "wxMyScrolledWindow.h"

////@begin XPM images
////@end XPM images


/*!
 * wxMyScrolledWindow type definition
 */

IMPLEMENT_DYNAMIC_CLASS( wxMyScrolledWindow, wxScrolledWindow )


/*!
 * wxMyScrolledWindow event table definition
 */

BEGIN_EVENT_TABLE( wxMyScrolledWindow, wxScrolledWindow )

////@begin wxMyScrolledWindow event table entries
    EVT_PAINT( wxMyScrolledWindow::OnPaint )
    EVT_ERASE_BACKGROUND( wxMyScrolledWindow::OnEraseBackground )
    EVT_LEFT_DOWN( wxMyScrolledWindow::OnLeftDown )
    EVT_KEY_DOWN( wxMyScrolledWindow::OnKeyDown )

////@end wxMyScrolledWindow event table entries

END_EVENT_TABLE()


/*!
 * wxMyScrolledWindow constructors
 */

wxMyScrolledWindow::wxMyScrolledWindow()
{
    Init();
}

wxMyScrolledWindow::wxMyScrolledWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
{
    Init();
    Create(parent, id, pos, size, style);
}


/*!
 * wxMyScrolledWindow creator
 */

bool wxMyScrolledWindow::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
{
////@begin wxMyScrolledWindow creation
    wxScrolledWindow::Create(parent, id, pos, size, style);
    CreateControls();
////@end wxMyScrolledWindow creation
    return true;
}


/*!
 * wxMyScrolledWindow destructor
 */

wxMyScrolledWindow::~wxMyScrolledWindow()
{
////@begin wxMyScrolledWindow destruction
////@end wxMyScrolledWindow destruction
}


/*!
 * Member initialisation
 */

void wxMyScrolledWindow::Init()
{
////@begin wxMyScrolledWindow member initialisation
////@end wxMyScrolledWindow member initialisation
}


/*!
 * Control creation for wxMyScrolledWindow
 */

void wxMyScrolledWindow::CreateControls()
{    
////@begin wxMyScrolledWindow content construction
    wxMyScrolledWindow* itemScrolledWindow1 = this;

    this->SetScrollbars(1, 1, 0, 0);
////@end wxMyScrolledWindow content construction
}


/*!
 * Should we show tooltips?
 */

bool wxMyScrolledWindow::ShowToolTips()
{
    return true;
}

/*!
 * Get bitmap resources
 */

wxBitmap wxMyScrolledWindow::GetBitmapResource( const wxString& name )
{
    // Bitmap retrieval
////@begin wxMyScrolledWindow bitmap retrieval
    wxUnusedVar(name);
    return wxNullBitmap;
////@end wxMyScrolledWindow bitmap retrieval
}

/*!
 * Get icon resources
 */

wxIcon wxMyScrolledWindow::GetIconResource( const wxString& name )
{
    // Icon retrieval
////@begin wxMyScrolledWindow icon retrieval
    wxUnusedVar(name);
    return wxNullIcon;
////@end wxMyScrolledWindow icon retrieval
}


/*!
 * wxEVT_PAINT event handler for ID_WXMYSCROLLEDWINDOW
 */

void wxMyScrolledWindow::OnPaint( wxPaintEvent& event )
{
////@begin wxEVT_PAINT event handler for ID_WXMYSCROLLEDWINDOW in wxMyScrolledWindow.
    // Before editing this code, remove the block markers.
    wxPaintDC dc(this);
////@end wxEVT_PAINT event handler for ID_WXMYSCROLLEDWINDOW in wxMyScrolledWindow. 
    dc.SetBackground(wxBrush(GetBackgroundColour()));
    dc.Clear();
}


/*!
 * wxEVT_ERASE_BACKGROUND event handler for ID_WXMYSCROLLEDWINDOW
 */

void wxMyScrolledWindow::OnEraseBackground( wxEraseEvent& event )
{
}


/*!
 * wxEVT_LEFT_DOWN event handler for ID_WXMYSCROLLEDWINDOW
 */

void wxMyScrolledWindow::OnLeftDown( wxMouseEvent& event )
{
    SetFocus();
}


/*!
 * wxEVT_KEY_DOWN event handler for ID_WXMYSCROLLEDWINDOW
 */

void wxMyScrolledWindow::OnKeyDown( wxKeyEvent& event )
{
    switch(event.GetKeyCode())
    {
    case WXK_TAB:
        wxMessageBox(_("Tab Pressed"));
        return;
    default:
        break;
    }
////@begin wxEVT_KEY_DOWN event handler for ID_WXMYSCROLLEDWINDOW in wxMyScrolledWindow.
    // Before editing this code, remove the block markers.
    event.Skip();
////@end wxEVT_KEY_DOWN event handler for ID_WXMYSCROLLEDWINDOW in wxMyScrolledWindow. 
}


Код

/////////////////////////////////////////////////////////////////////////////
// Name:        wxTestMainFrame.cpp
// Purpose:     
// Author:      Volodymir (T-Rex) Tryapichko
// Modified by: 
// Created:     23/01/2008 19:25:24
// RCS-ID:      
// Copyright:   Volodymir (T-Rex) Tryapichko, 2008
// Licence:     
/////////////////////////////////////////////////////////////////////////////

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

////@begin includes
////@end includes

#include "wxTestMainFrame.h"
#include "wxTestApp.h"

////@begin XPM images
////@end XPM images


/*!
 * wxTestMainFrame type definition
 */

IMPLEMENT_CLASS( wxTestMainFrame, wxFrame )


/*!
 * wxTestMainFrame event table definition
 */

BEGIN_EVENT_TABLE( wxTestMainFrame, wxFrame )

////@begin wxTestMainFrame event table entries
    EVT_MENU( wxID_EXIT, wxTestMainFrame::OnExitClick )

////@end wxTestMainFrame event table entries

END_EVENT_TABLE()


/*!
 * wxTestMainFrame constructors
 */

wxTestMainFrame::wxTestMainFrame()
{
    Init();
}

wxTestMainFrame::wxTestMainFrame( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
    Init();
    Create( parent, id, caption, pos, size, style );
}


/*!
 * wxTestMainFrame creator
 */

bool wxTestMainFrame::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
////@begin wxTestMainFrame creation
    wxFrame::Create( parent, id, caption, pos, size, style );

    CreateControls();
    Centre();
////@end wxTestMainFrame creation
    return true;
}


/*!
 * wxTestMainFrame destructor
 */

wxTestMainFrame::~wxTestMainFrame()
{
////@begin wxTestMainFrame destruction
////@end wxTestMainFrame destruction
}


/*!
 * Member initialisation
 */

void wxTestMainFrame::Init()
{
////@begin wxTestMainFrame member initialisation
////@end wxTestMainFrame member initialisation
}


/*!
 * Control creation for wxTestMainFrame
 */

void wxTestMainFrame::CreateControls()
{    
////@begin wxTestMainFrame content construction
    wxTestMainFrame* itemFrame1 = this;

    wxMenuBar* menuBar = new wxMenuBar;
    wxMenu* itemMenu3 = new wxMenu;
    itemMenu3->Append(wxID_EXIT, _("Exit\tAlt+F4"), _T(""), wxITEM_NORMAL);
    menuBar->Append(itemMenu3, _("File"));
    itemFrame1->SetMenuBar(menuBar);

    wxStatusBar* itemStatusBar5 = new wxStatusBar( itemFrame1, ID_MAIN_STATUSBAR, wxST_SIZEGRIP|wxNO_BORDER );
    itemStatusBar5->SetFieldsCount(2);
    itemFrame1->SetStatusBar(itemStatusBar5);

    wxBoxSizer* itemBoxSizer6 = new wxBoxSizer(wxVERTICAL);
    itemFrame1->SetSizer(itemBoxSizer6);

    wxPanel* itemPanel7 = new wxPanel( itemFrame1, ID_PANEL1, wxDefaultPosition, wxDefaultSize, wxNO_BORDER );
    itemBoxSizer6->Add(itemPanel7, 1, wxGROW, 0);

    wxBoxSizer* itemBoxSizer8 = new wxBoxSizer(wxVERTICAL);
    itemPanel7->SetSizer(itemBoxSizer8);

    wxMyScrolledWindow* itemScrolledWindow9 = new wxMyScrolledWindow( itemPanel7, ID_FOREIGN, wxDefaultPosition, wxSize(100, 100), wxSIMPLE_BORDER );
    itemBoxSizer8->Add(itemScrolledWindow9, 1, wxGROW, 0);

    wxButton* itemButton10 = new wxButton( itemPanel7, ID_BUTTON, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer8->Add(itemButton10, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);

////@end wxTestMainFrame content construction
}


/*!
 * Should we show tooltips?
 */

bool wxTestMainFrame::ShowToolTips()
{
    return true;
}

/*!
 * Get bitmap resources
 */

wxBitmap wxTestMainFrame::GetBitmapResource( const wxString& name )
{
    // Bitmap retrieval
////@begin wxTestMainFrame bitmap retrieval
    wxUnusedVar(name);
    return wxNullBitmap;
////@end wxTestMainFrame bitmap retrieval
}

/*!
 * Get icon resources
 */

wxIcon wxTestMainFrame::GetIconResource( const wxString& name )
{
    // Icon retrieval
////@begin wxTestMainFrame icon retrieval
    wxUnusedVar(name);
    return wxNullIcon;
////@end wxTestMainFrame icon retrieval
}


/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for wxID_EXIT
 */

void wxTestMainFrame::OnExitClick( wxCommandEvent& event )
{
    Close();
}


Добавлено через 6 минут и 52 секунды
Хм.. возможно "более лучшее" решение
http://docs.wxwidgets.org/trunk/classwx_window.html

Цитата

# wxWANTS_CHARS:
Use this to indicate that the window wants to get all char/key events for all keys - even for keys like TAB or ENTER which are usually used for dialog navigation and which wouldn't be generated without this style. If you need to use this style in order to get the arrows or etc., but would still like to have normal keyboard navigation take place, you should call Navigate in response to the key events for Tab and Shift-Tab. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)