QWinWidget内部MFC对话框不重绘或响应Tab /箭头键

时间:2022-01-26 09:58:55

I am using a QWinWidget inside of an MFC dialog and the QWinWidget is not drawing itself correctly and it is not handling keyboard input correctly.

我在MFC对话框中使用QWinWidget,并且QWinWidget没有正确绘制,并且没有正确处理键盘输入。

Repainting [Unsolved]

Within the QWinWidget, I have a QTableWidget. When I scroll the QTableWidget, it does not redraw itself until I stop scrolling, at which point it redraws everything. Similarly, I can type into cells in the QTableWidget and the control is not updated until I force it to re-update by scrolling up or down (it re-updates when the scrolling stops).

在QWinWidget中,我有一个QTableWidget。当我滚动QTableWidget时,它不会重绘自己,直到我停止滚动,此时它会重绘所有内容。类似地,我可以在QTableWidget中键入单元格,并且控件不会更新,直到我强制它通过向上或向下滚动重新更新(它在滚动停止时重新更新)。

Since this QWinWidget is housed in an MFC CDialog, I tried overriding the CDialog's OnPaint method and only call the QWinWidget::repaint method, however this has the opposite problem where now only the QWinWidget is updated and the CDialog is never redrawn, resulting in artifacts. If I call QWinWidget::repaint and CDialog::OnPaint, the result is the same as not overriding the OnPaint method. Has anyone ever seen this problem or know how to resolve it?

由于这个QWinWidget位于MFC CDialog中,我尝试重写CDialog的OnPaint方法并且只调用QWinWidget :: repaint方法,但是这有相反的问题,现在只更新QWinWidget而且CDialog永远不会被重绘,导致伪像。如果我调用QWinWidget :: repaint和CDialog :: OnPaint,结果与不覆盖OnPaint方法的结果相同。有没有人见过这个问题或知道如何解决它?

Keyboard Input [Solved]

None of the controls within the QWinWidget respond to the tab key or arrow keys correctly. The tab/arrow keys simply skip over the entire QWinWidget (and all child controls). Even if I click inside the QWinWidget and select a control, the next time I press the tab key, it skips the focus completely out of the entire QWinWidget.

QWinWidget中的所有控件都没有正确响应Tab键或箭头键。选项卡/箭头键只是跳过整个QWinWidget(以及所有子控件)。即使我在QWinWidget内部单击并选择一个控件,下次我按Tab键时,它会完全跳过整个QWinWidget。

I noticed that the QWinWidget has two functions, QWinWidget::focusNextPrevChild and QWinWidget::focusInEvent and both of them have a comment header saying "\reimp". Am I supposed to override these functions in order to get correct tab functionality? If so, how can these functions be implemented for correct tab functionality.

我注意到QWinWidget有两个函数,QWinWidget :: focusNextPrevChild和QWinWidget :: focusInEvent,它们都有一个注释标题“\ reimp”。我是否应该覆盖这些功能以获得正确的标签功能?如果是这样,如何实现这些功能以实现正确的选项卡功能。

4 个解决方案

#1


I have fixed the keyboard input issue. The QWinWidget class needed some changes:

我修复了键盘输入问题。 QWinWidget类需要进行一些更改:

in the QWinWidget::init method, the WS_TABSTOP must be added to the window style:

在QWinWidget :: init方法中,必须将WS_TABSTOP添加到窗口样式中:

SetWindowLong(winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP);

Also, the QWinWidget::winEvent method needs to respond to the WM_GETDLGCODE to let Windows know that it is interested in receiving key/tab inputs. I had to add this if block:

此外,QWinWidget :: winEvent方法需要响应WM_GETDLGCODE,让Windows知道它有兴趣接收键/标签输入。我必须添加这个if块:

if(msg->message == WM_GETDLGCODE)
{
   *result = DLGC_WANTARROWS | DLGC_WANTTAB;
   return(true);
}

I am still working on getting the widget to paint properly.

我仍在努力让小部件正确绘制。

#2


I don't know about whether you need to reimplement the focusNextPrevChild() and focusInEvent() functions, but I do know that the "\reimp" in the comment header is part of Qt's documentation generation, which merely specifies that the function was a reimplementation of another function in a parent class.

我不知道你是否需要重新实现focusNextPrevChild()和focusInEvent()函数,但我知道注释头中的“\ reimp”是Qt文档生成的一部分,它只是指定函数是一个在父类中重新实现另一个函数。

#3


No idea about the keyboard input, but concerning the repainting: have you tried calling QWinWidget::repaint() in the CDialog's OnPaint method AFTER calling the CDialog::OnPaint()?

不知道键盘输入,但关于重新绘制:你是否尝试在调用CDialog :: OnPaint()之后在CDialog的OnPaint方法中调用QWinWidget :: repaint()?

#4


Thanks! It works for me! I have fixed an arrow keys navigation issue for a QTableView inside a QWinWidget. I am using Qt5.3.0 and qtwinmigrate 2.8. The QWinWidget::nativeEvent method needs to be modified.

谢谢!这个对我有用!我已经为QWinWidget中的QTableView修复了箭头键导航问题。我使用的是Qt5.3.0和qtwinmigrate 2.8。需要修改QWinWidget :: nativeEvent方法。

#if QT_VERSION >= 0x050000
bool QWinWidget::nativeEvent(const QByteArray &, void *message, long *result)
#else
...
{
    ...
    if (msg->message == WM_SETFOCUS) {
        ...
    } else if (msg->message == WM_GETDLGCODE) {
        *result = DLGC_WANTALLKEYS;
        return true;
    }

    return false;
}

#1


I have fixed the keyboard input issue. The QWinWidget class needed some changes:

我修复了键盘输入问题。 QWinWidget类需要进行一些更改:

in the QWinWidget::init method, the WS_TABSTOP must be added to the window style:

在QWinWidget :: init方法中,必须将WS_TABSTOP添加到窗口样式中:

SetWindowLong(winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP);

Also, the QWinWidget::winEvent method needs to respond to the WM_GETDLGCODE to let Windows know that it is interested in receiving key/tab inputs. I had to add this if block:

此外,QWinWidget :: winEvent方法需要响应WM_GETDLGCODE,让Windows知道它有兴趣接收键/标签输入。我必须添加这个if块:

if(msg->message == WM_GETDLGCODE)
{
   *result = DLGC_WANTARROWS | DLGC_WANTTAB;
   return(true);
}

I am still working on getting the widget to paint properly.

我仍在努力让小部件正确绘制。

#2


I don't know about whether you need to reimplement the focusNextPrevChild() and focusInEvent() functions, but I do know that the "\reimp" in the comment header is part of Qt's documentation generation, which merely specifies that the function was a reimplementation of another function in a parent class.

我不知道你是否需要重新实现focusNextPrevChild()和focusInEvent()函数,但我知道注释头中的“\ reimp”是Qt文档生成的一部分,它只是指定函数是一个在父类中重新实现另一个函数。

#3


No idea about the keyboard input, but concerning the repainting: have you tried calling QWinWidget::repaint() in the CDialog's OnPaint method AFTER calling the CDialog::OnPaint()?

不知道键盘输入,但关于重新绘制:你是否尝试在调用CDialog :: OnPaint()之后在CDialog的OnPaint方法中调用QWinWidget :: repaint()?

#4


Thanks! It works for me! I have fixed an arrow keys navigation issue for a QTableView inside a QWinWidget. I am using Qt5.3.0 and qtwinmigrate 2.8. The QWinWidget::nativeEvent method needs to be modified.

谢谢!这个对我有用!我已经为QWinWidget中的QTableView修复了箭头键导航问题。我使用的是Qt5.3.0和qtwinmigrate 2.8。需要修改QWinWidget :: nativeEvent方法。

#if QT_VERSION >= 0x050000
bool QWinWidget::nativeEvent(const QByteArray &, void *message, long *result)
#else
...
{
    ...
    if (msg->message == WM_SETFOCUS) {
        ...
    } else if (msg->message == WM_GETDLGCODE) {
        *result = DLGC_WANTALLKEYS;
        return true;
    }

    return false;
}