Ввод с клавиатуры не работает должным образом при использовании хостинга виджета Qt на CDialog с QWinWidget - PullRequest
1 голос
/ 05 декабря 2011

Я постепенно переносю приложение из MFC в Qt и использую для этой цели MFCMigrationFramework .

Виджет Qt, который размещен наДиалог MFC не обрабатывает такие клавиши, как Tab , Стрелки , Ввод , Esc .Проблема с Tab и стрелками была частично решена с помощью этого решения :

Я подкласс QWinWidget и сделал следующие вещи: Конструктор:

SetWindowLong(winId(), GWL_STYLE, GetWindowLong(winId(), GWL_STYLE) | WS_TABSTOP);

Переопределить winEvent:

bool winEvent(MSG *msg, long *result)
{
  switch(msg->message)
  {
    case WM_GETDLGCODE:
      *result = DLGC_WANTARROWS | DLGC_WANTTAB;
      return true;
  }

  return __super::winEvent(msg, result);
}

Чтобы скопировать в буфер обмена, переключите представление в режим обычного текста

Это работает, за исключением одной проблемы: невозможно получить доступ к элементам управления в родительском диалоге (MFC) с помощью Клавиша Tab , фокусировка циклически выполняется только через дочерний элемент управления Qt ( первый выпуск ).

Второй выпуск : Ввод и клавиши Esc обрабатываются только родительским диалогом MFC.Например, невозможно закрыть открытое всплывающее окно со списком (расположенное в виджете Qt) нажатием клавиши Enter или Esc - вместо этого закрывается диалоговое окно ( CDialog :: OnOK или CDialog :: OnCancel

Я пробовал это

case WM_GETDLGCODE:
  *result = DLGC_WANTARROWS | DLGC_WANTTAB | DLGC_WANTALLKEYS;

, но в этом случае CDialog больше не обрабатывает клавиши Esc и Enter.

Каково правильное решение, чтобы справиться с такой ситуацией?

1 Ответ

2 голосов
/ 06 июля 2012

Что касается вашей первой проблемы: то, что для меня сработало, - это решить, основываясь на текущей точке фокусировки, если вы находитесь в «конечной точке» в цепочке фокусировки.Если вы находитесь в конце и получаете вкладку (или в начале и получаете вкладку shift), то не включайте DLGC_WANTTAB в возвращаемое значение:

else if (msg->message == WM_GETDLGCODE)
{
  // Initialize our result, as we always want arrows
  *result = DLGC_WANTARROWS;

  // Check to see if we want tabs
  if (msg->wParam == VK_TAB)
  {
    // Was this a tab or a backtab?
    QWidget *pFocusChainEndpoint = NULL;
    if (::GetKeyState(VK_SHIFT) < 0)
    {
      pFocusChainEndpoint = m_pFirstTabStop;
    }
    else
    {
      pFocusChainEndpoint = m_pFinalTabStop;
    }

    // Determine our current-focusing widget
    QWidget *pCurrent = focusWidget();
    if (pCurrent == NULL)
    {
      // We have no focus, so we don't want the tab event
      return true;
    }

    // If we are *not* at a relevant endpoint in the focus chain,
    // we want to handle the tab event
    if (pCurrent != pFocusChainEndpoint)
    {
      *result |= DLGC_WANTTAB;
    }
  }

  // This message has been handled
  return true;
}

m_pFirstTabStop и m_pFinalTabStop определяются в коде show():

  // Determine the first link in our focus chain
  m_pFirstTabStop = nextInFocusChain();
  Q_ASSERT(m_pFirstTabStop != NULL);
  if (m_pFirstTabStop == NULL)
  {
    // We have no endpoint
    return;
  }
  QString qstrChainObjectName = m_pFirstTabStop->objectName();
  while (!(m_pFirstTabStop->focusPolicy() & Qt::TabFocus)
    || qstrChainObjectName.left(3) == "qt_")
  {
    m_pFirstTabStop = m_pFirstTabStop->nextInFocusChain();
    if (m_pFirstTabStop == this || m_pFirstTabStop == NULL)
    {
      // We've looped through them all, and none require focus --- perhaps the
      // control is just labels --- so we have a NULL tab stop
      m_pFirstTabStop = NULL;
      return;
    }
    qstrChainObjectName = m_pFirstTabStop->objectName();
  }

  // Determine the last link in our focus chain
  m_pFinalTabStop = previousInFocusChain();
  Q_ASSERT(m_pFinalTabStop != NULL);
  if (m_pFinalTabStop == NULL)
  {
    // We have no endpoint
    return;
  }
  qstrChainObjectName = m_pFinalTabStop->objectName();
  while (!(m_pFinalTabStop->focusPolicy() & Qt::TabFocus)
    || qstrChainObjectName.left(3) == "qt_")
  {
    m_pFinalTabStop = m_pFinalTabStop->previousInFocusChain();
    if (m_pFinalTabStop == this || m_pFinalTabStop == NULL)
    {
      // We've looped through them all, and none require focus --- perhaps the
      // control is just labels --- so we have a NULL tab stop
      m_pFinalTabStop = NULL;
      return;
    }
    qstrChainObjectName = m_pFinalTabStop->objectName();
  }

Хотя я не проверял этот случай, он должен иметь возможность правильно обрабатывать пользовательский интерфейс только с элементами управления без вкладок (например,просто QLabels).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...