使用带有QWinWidget的CDialog上的托管Qt小部件时,键盘输入无法正常工作
Keyboard input doesn't work properly when using hosting Qt widget on CDialog with QWinWidget
我逐渐将应用程序从MFC迁移到Qt,并为此目的使用MFCMigrationFramework。
Qt小部件放置在MFC对话框上不处理诸如Tab, 箭头, Enter, Esc等键。这个解决方案部分解决了制表符和箭头的问题:
我已经子类化了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键。
处理这种情况的正确解决方案是什么?
关于你的第一个问题:对我来说有效的是根据当前的焦点来决定你是否处于焦点链中的"端点"。如果您在末尾得到一个制表符(或者在开头得到一个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();
}
虽然我没有测试这个案例,它应该能够正确地处理只有非表格控件的UI(例如,只有QLabels)
相关文章:
- 视窗键盘输入 c++
- 将鼠标和键盘输入发送到 unity3d 游戏 (Rust)
- C ++异步键盘输入(标准方式)
- 盖奇不读取键盘输入
- 在 Linux 上C++:在作为 systemd 服务运行时侦听键盘输入
- 是否可以将键盘输入绑定到 Win32 中的单个应用程序?
- 使用 Windows API c++ 的键盘输入
- 如何使 std::istream 从键盘获取输入(如 std::cin)?
- 如何检查从键盘输入的特定整数值是否存在于C++文件中的一行或多行中
- 为什么如果我从键盘输入EOF克里昂不要在运行窗口打印程序的输出?
- 从特定 USB 端口捕获键盘输入
- 使用 fgets() 从键盘读取时从以前的输入读取换行符
- 使用 sfml 进行 2 个键盘输入
- 如何对并行键盘输入进行编程
- 区分键盘记录器中的密码和其他类型的键盘输入
- 如何通过键盘或分数文件输入分数
- OpenGL/GLFW/GLM-键盘输入无反应
- 在 MFC 应用中模拟应用内的键盘输入C++
- 如何在C++中终止具有键盘输入的侦听 TCP 服务器
- 通过键盘输入字符串数组和 int 数组的数组大小