我正在逐步将应用程序从 MFC 迁移到 Qt 并使用 MFCMigrationFramework 来实现此目的。
放置在MFC对话框上的Qt小部件无法处理标签,箭头,输入, Esc <等关键字/ strong>即可。 选项卡和箭头的问题部分通过this solution解决:
我已经将 QWinWidget 子类化,并做了下面的事情: 构造:
SetWindowLong(winId(), GWL_STYLE, GetWindowLong(winId(), GWL_STYLE) | WS_TABSTOP);
Overriden 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);
}
要复制到剪贴板,请将视图切换为纯文本模式
除了一个问题之外它是有效的:使用 Tab 键无法在父对话框(MFC)上获得控件,仅通过子Qt控件(第一个问题)进行焦点循环
第二个问题:输入, Esc 键仅由父MFC对话框处理。例如,按Enter或Esc键关闭打开的组合框弹出窗口(位于Qt小部件上)是不可能的 - 对话框已关闭( CDialog :: OnOK 或 CDialog :: OnCancel 被称为。)
我试过这个
case WM_GETDLGCODE:
*result = DLGC_WANTARROWS | DLGC_WANTTAB | DLGC_WANTALLKEYS;
但在这种情况下 CDialog 不再处理Esc和Enter键。
处理这种情况的正确解决方案是什么?
答案 0 :(得分:2)
关于你的第一个问题:对我来说有用的是根据当前的焦点来决定你是否处于焦点链的“终点”。如果您在最后并获得一个标签(或在开头并获得一个班次标签),那么请不要在返回值中包含 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();
}
虽然我没有测试这种情况,但它应该能够正确处理只有非可列表控件的UI(例如只有QLabel)。